GitLab: why auto-merge was refused, merged at once, or canceled
Auto-merge asks GitLab to merge a merge request once its merge checks pass. Through the merge API it is auto_merge: true, from GitLab 17.11; before that it was merge_when_pipeline_succeeds: true, which 17.11 deprecated. Since GitLab 17.7 it waits for all the merge checks, not only the pipeline (GitLab's auto-merge docs). GitLab can still answer 405, merge it on the spot, or cancel it later. All of the following was checked on October 24, 2026 in GitLab's source (lib/api/merge_requests.rb, app/services/auto_merge/merge_when_checks_pass_service.rb, app/models/merge_request.rb) and its merge API docs.
What GitLab does with auto_merge
- First, the same checks as any merge:
400when the group requires the commit SHA,401when your account may not merge into the target branch,409when the source branch moved. See why the merge was refused. - It waits for the pipeline, approvals, requested changes, unresolved threads, a draft, conflicts, other merge requests that block this one, external status checks, security policies, locked files and paths, a required Jira issue, a title pattern and a Merge after date.
- It does not wait for a closed merge request, a source branch without commits, or a rebase the merge method needs (
need_rebase). - It does not wait when nothing is left to wait for: the merge request can merge now and its pipeline is not in progress. With Pipelines must succeed, a pipeline is in progress until it is complete; without it, only while it is waiting or running, so a pipeline stopped at a manual job is not waited for.
- When it does not wait, GitLab merges at once if the pipeline allows it: there is no pipeline and none is being created, or the latest one succeeded. The answer is then the merged merge request, with
"state":"merged". If the merge request turns out not to be mergeable, the answer is422 Branch cannot be merged. - Otherwise the answer is
{"message":"405 Method Not Allowed"}, the same as for an ordinary merge that is stopped, with no reason given.
When auto-merge is set, the answer is 200 with "state":"opened" and "merge_when_pipeline_succeeds":true. On a project with merge trains, the request adds the merge request to the train instead, since GitLab 19.1.
The two 405s that surprise
- A rebase is needed. With the fast-forward or semi-linear merge method and without automatic rebase before merge, a merge request behind its target branch needs a rebase. Auto-merge does not wait for one, so while the pipeline runs GitLab answers 405, even if a review is also missing.
- The pipeline failed, and the project does not require a successful pipeline. If nothing else stops the merge request, GitLab will not wait (nothing is left to wait for) and will not merge at once (the pipeline did not succeed): 405. An ordinary merge, without
auto_merge, works. With Pipelines must succeed, GitLab sets auto-merge on a failed pipeline and waits, and merges if a retried job succeeds.
When GitLab cancels auto-merge
From GitLab's docs, it cancels auto-merge when new commits are pushed to the source branch, so that they get a review. It also cancels it when commits are added to the target branch and the merge method is fast-forward or semi-linear without automatic rebase before merge. Keeping it set when that rebase is on came in GitLab 19.3, behind a feature flag that is off by default. The merge request's activity shows a note when GitLab cancels or aborts auto-merge.
Cancelling it
POST /projects/:id/merge_requests/:merge_request_iid/cancel_auto_merge, from GitLab 19.5:201with the merge request;403 Forbiddenwhen you may not cancel it;409Can't cancel the automatic mergewhen it is not set to auto-merge.POST …/cancel_merge_when_pipeline_succeeds, the endpoint older versions have, deprecated in 19.5:401when you may not cancel it. When it is not set, the answer is still201 Created, with{"message":"Can't cancel the automatic merge","status":"error","http_status":406}: the 406 is only in the body, so readstatus.- The author may cancel it, and so may anyone who may merge it.
What to do
- 405 with a rebase needed: rebase, and set auto-merge again while the new pipeline runs.
- 405 after a failed pipeline: merge it without auto-merge, or retry the failed jobs and set auto-merge while they run.
- Merged at once: nothing was left to wait for. GitLab waits only for the checks the project turns on, such as required approvals or resolved threads.
- Canceled: look at the new commits, then set auto-merge again.
- 409 or
"status":"error"on cancel: there was nothing to cancel. It was merged, canceled already, or never set;merge_when_pipeline_succeedson the merge request istrueonly while it is set.
GitLab merge requests in IntelliJ IDEA
Merge Request Inbox for GitLab, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, shows a merge request's merge checks before you merge and merges the head commit you had on screen. While the pipeline runs, its Merge dialog offers auto-merge, and sends both auto_merge and merge_when_pipeline_succeeds, so GitLab versions before and after 17.11 understand it. When GitLab merges at once instead, it says the merge request was merged. From version 1.0.15, when GitLab refuses auto-merge (405), it says that auto-merge does not wait for a rebase the merge method needs, and to merge without auto-merge when the pipeline has already ended without succeeding; when GitLab answers but sets nothing, it says so. Before, it gave the message for an ordinary merge, which names a draft, threads, approvals and the pipeline, all of which auto-merge waits for. Reading is free; approving, commenting and merging are Pro (US$1.50 a month, with a 30-day trial).
GITLAB is a trademark of GitLab Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by GitLab Inc. or JetBrains.
More: GitLab merge refused (400, 401, 405, 409, 422) · GitLab rebase refused or failed (403, 409) · GitLab approval refused (401, 409) · GitLab "insufficient_scope" · GitLab 401 "invalid_token" · GitLab merge request list refused (400, 404) · GitLab merge request changes cut short ("1000+", too_large) · GitLab 429 "Retry later" (rate limits) · GitLab merge refused or failed over squashing · GitLab "compare_timeout": true (diff limits) · GitLab merge request plugins for IntelliJ IDEA, compared · 日本語