GitLab がマージを断った理由
API でのマージが失敗すると、GitLab は5つのどれかで答え、それぞれ意味が違います。GitLab のマージの API の説明を、ソース(lib/api/merge_requests.rb)と突き合わせました。405 はいまマージの条件のどれかで止まっている、409 は元のブランチが動いた、422 はマージそのものが失敗した、401 はアカウントが対象のブランチへマージできない、400 はグループかインスタンスがコミットの SHA を求めている、です。
答えの一覧
- 405
{"message":"405 Method Not Allowed"}:いまはマージできません。マージの条件のどれかで止まっています(下を参照)。 - 409
SHA does not match HEAD of source branch: …(和訳:SHA が元のブランチの先頭と合いません):レビューした人が見たコミットを指定してマージしたが、元のブランチの先頭が別のコミットになっている。GitLab はコロンのあとに新しい先頭を書きます。見た後に誰かが push しました。 - 422
Branch cannot be merged(和訳:ブランチをマージできません):GitLab はマージを試みたが、マージされなかった。ソースでは、最後の瞬間にマージできない状態だと分かったとき、またはマージの処理がマージしなかったときです。 - 401
401 Unauthorized:この窓口では、トークンが悪いという意味ではありません。GitLab はアカウントが対象のブランチを更新できるか(can_be_merged_by?)を確かめるので、たとえば自分の役割ではマージできない保護ブランチだと 401 になります。 - 400
SHA must be provided when merging(和訳:マージには SHA が必要です):グループかインスタンスの設定「マージリクエストの API でコミットの SHA を必須にする」が入っていて、呼び出しに SHA が無かった。
どの条件で止まっているか(405)
マージリクエストを読んで detailed_merge_status を見ます:
curl -H "PRIVATE-TOKEN: your-token" "https://gitlab.com/api/v4/projects/group%2Fproject/merge_requests/42"
主な値です(GitLab のマージの状態の一覧より):
draft_status:下書きです。準備完了にします。not_approved:まだ承認が要ります。requested_changes:レビュアーが変更を求めています。discussions_not_resolved:先にすべてのスレッドを解決する必要があります。ci_must_passかci_still_running:先にパイプラインが成功する必要があります。conflict:元のブランチと対象のブランチが競合しています。need_rebase:元のブランチを対象のブランチへリベースする必要があります。not_open:開いていません。merge_request_blocked:先に別のマージリクエストをマージする必要があります。checking・unchecked・preparing:GitLab がまだ確かめ終わっていません。確認は裏で進むので、少し後にもう一度読みます。
一覧には、ステータスチェック・セキュリティポリシー・ロックされたファイルやパス・必須の Jira の課題・タイトルの形式の値もあります。自動マージ(auto_merge)を頼めば、条件が満たされたときにマージされます。自動マージにも別の 405 があります。自動マージが待つものへ。
直し方
- 405:
detailed_merge_statusが言うものを直してから、もう一度マージする。 - 409:新しいコミットを見てから、新しい先頭でマージする。
- 422:マージリクエストを読み直す。
conflictかneed_rebaseになっていれば、先に解決するかリベースする。 - 401:メンテナーに頼むか、設定 > リポジトリ > 保護ブランチで、対象のブランチに誰がマージできるかを確かめる。
- 400:レビューした先頭のコミットを
shaに入れて送る。
IntelliJ IDEA の「Review has conversations that must be resolved」と「Source branch must be rebased before merging」
IntelliJ IDEA に入っている GitLab のマージリクエストの機能は、マージリクエストの状態にこの2つの行を出します。ソース(2026年10月30日に確認)では:
- 「Review has conversations that must be resolved」(解決していない会話がある)は、マージ先のプロジェクトで All threads must be resolved がオンで(GraphQL の
onlyAllowMergeIfAllDiscussionsAreResolved)、マージリクエストの解決できるスレッドのうち1つでも解決していないときに出ます。誰かが返信するまで解決できない普通のコメントは数えません(GitLabMergeRequestStatusViewModel.kt・GitLabMergeRequestDiscussionUtil.kt)。GitLab がdiscussions_not_resolvedと呼ぶ場合です。設定は Settings > Merge requests > Merge checks にあります(GitLab の説明「Prevent merge unless all threads are resolved」)。この行がいつも出るという報告は、2024年5月29日に直ったと閉じられています(IJPL-81324)。 - 「Source branch must be rebased before merging」(マージの前にソースブランチのリベースが要る)は、Rebase のボタンと一緒に、マージリクエストが開いていて、自分がマージでき、マージ先のプロジェクトが早送り(fast-forward)でマージする設定で(
mergeRequestsFfOnlyEnabled)、GitLab がソースブランチのリベースが要ると言うとき(shouldBeRebased)に出ます。GitLab がneed_rebaseと呼ぶ場合で、早送りのマージは、ソースブランチに無いコミットがマージ先に無いときだけできます(GitLab の説明「Fast-forward merge」)。Rebase を押すと、GitLab にサーバーの上でソースブランチをリベースするよう頼み(PUT /projects/:id/merge_requests/:merge_request_iid/rebase)、GitLab がリベース中と言う間はマージリクエストを読み直します。手元のクローンでは何もしません(GitLabMergeRequestDetailsStatusChecksComponentFactory.kt・GitLabMergeRequestFullDetails.kt・GitLabMergeRequest.kt)。GitLab がリベースしないときはGitLab がリベースしなかった理由へ。
IntelliJ IDEA の「All required checks have passed」「Checks in progress…」「Checks failed」
IntelliJ IDEA に入っている GitLab のマージリクエストの機能は、マージリクエストの状態にパイプラインの行も1つ、ジョブの一覧を開く Details… のリンクと一緒に出します。ソース(2026年10月30日に確認)では、この行はマージリクエストの最新のパイプライン(head pipeline)のジョブ(1,000件まで)を読み、失敗してよいジョブ(allowFailure)でなければ必須のジョブとして数えます:
- 必須のジョブが全部成功したとき(必須のジョブが1つも無いときも)は「All required checks have passed」(必須のチェックは全部通った)。
- そうでなければ、動いているジョブと失敗したジョブが両方あると「Checks in progress, and some already failed…」(チェック中で、もう失敗もある)、動いているジョブがあって失敗が無いと「Checks in progress…」(チェック中)、それ以外はすべて「Checks failed」(チェックが失敗)。
- 失敗(failed)と取り消し(canceled)は失敗に数え、created・pending・preparing・running・scheduled・waiting for resource は動いている方に数えます。手動(manual)とスキップ(skipped)はどちらにも入らないので、必須のジョブが手動かスキップのままで、動いている物も失敗も無いと「Checks failed」と出ます。手動のジョブが必須になるのは
allow_failure: falseのときで、rulesの中のwhen: manualではこれが既定です(止める手動ジョブ:誰かが動かすまで、パイプラインはそのステージで止まる)。rulesの外の手動ジョブは、既定では失敗してよいジョブです(GitLab の説明「allow_failure」・「Types of manual jobs」・IntelliJ IDEA:GitLabMergeRequestStatusViewModel.kt・pipeline.graphql・CodeReviewDetailsStatusComponentFactory.kt)。 - 最新のパイプラインが無いか、パイプラインにジョブが無いときは、この行は出ません。
IntelliJ IDEA の「Branch has conflicts that must be resolved」
IntelliJ IDEA に入っている GitLab のマージリクエストの機能は、マージリクエストの状態に「Branch has conflicts that must be resolved」(解決が要る衝突がある)の行も、Resolve のリンクと一緒に出します。ソース(2026年10月30日に確認)では、この行は GraphQL のマージの状態(mergeStatusEnum)に従います。CANNOT_BE_MERGED(ソースブランチとターゲットブランチに衝突がある)でこの行が出て、CHECKING・UNCHECKED・CANNOT_BE_MERGED_RECHECK(まだ確かめていない・前の状態は CANNOT_BE_MERGED)と、詳しい情報を読み込む前は、代わりに「Checking branch for conflicts」(衝突を確かめ中)が出ます。CAN_BE_MERGED では出ません(GitLab の説明「MergeStatus」・IntelliJ IDEA:GitLabResolveConflictsLocallyViewModel.kt・GitLabMergeRequestFullDetails.kt・GitLabMergeRequestDetailsStatusChecksComponentFactory.kt・CodeReviewDetailsStatusComponentFactory.kt)。Resolve を押すと、リベースかマージかを聞いて、ターゲットブランチを fetch し、ソースブランチをチェックアウトして(ソースのプロジェクトがフォークで、手元のクローンにまだそのリモートが無ければ足して)、手元のクローンで、ソースブランチをターゲットブランチの上にリベースするか、ターゲットブランチをソースブランチにマージします。衝突は IDE の中で解き、マージリクエストが変わるのは push したときだけです。リベースした後の push は強制 push になります(ResolveConflictsLocallyViewModel.kt)。Resolve は、リポジトリがマージやリベースの途中のとき(「Merge is already in progress」)、GitLab がソースのプロジェクトを返さないとき(「The source project is private or does not exist」)、今のブランチがすでにソースブランチを追っていて、GitLab が差分の基点として返すコミット(diffRefs の baseSha・「Merge base of the branch the comment was made on」)がその履歴にあるとき(「Already resolved locally, push your changes to resolve」)は、理由を添えて押せなくなります(CollaborationToolsBundle.properties・GitLabBundle.properties・GitLabResolveConflictsLocallyViewModel.kt)。
IntelliJ IDEA で GitLab のマージリクエストを見るなら
Lesstep の Merge Request Inbox for GitLab は、JetBrains IDE(2024.1 以降)のプラグインです。マージの前に、マージリクエストのマージの条件を見せます。承認・変更の依頼・未解決のスレッド・パイプライン・競合と、detailed_merge_status が言う GitLab のほかの理由を、マージを止めているものから順に並べます。マージするのは、画面に出ていた先頭のコミットです。GitLab が断ったときは、どの場合かを言います。405 なら今はマージできないのでマージの条件を見るように、409 なら元のブランチが変わったので読み直すように、422 なら GitLab がマージできなかったと GitLab の文を添えて、401 なら役割かプロジェクトの設定が許していないかもしれない、と。リベースが要るときは、リベースを勧めます。読むのは無料、承認・コメント・マージは Pro(月 US$1.50・30日間の無料試用つき)です。画面は日本語です。
GITLAB は GitLab Inc. の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitLab Inc.・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:GitLab の自動マージの断り(405)・取り消し · GitLab の 404「Project Not Found」 · GitLab の「insufficient_scope」 · GitLab の 401「invalid_token」 · GitLab の承認の断り(401・409) · GitLab のコメント・スレッドの断り(400・403) · GitLab のマージリクエストが作れない(409・422・400) · GitLab のリベースの断り・失敗(403・409) · GitLab の MR の一覧の断り(400・404) · GitLab の MR の変更が欠ける(「1000+」・too_large) · GitLab の 429「Retry later」(回数の上限) · GitLab のスカッシュでマージが断られる・失敗する · GitLab の「compare_timeout」(差分の上限) · JetBrains の IDE で GitLab のマージリクエストを扱う · English