GitLab: why the merge request was not created
Creating a merge request through the API (POST /projects/:id/merge_requests with source_branch, target_branch and title) is refused with 409, 422, 400 or 403, and GitLab's API documentation does not list what each means. All of this is from GitLab's source (lib/api/merge_requests.rb, handle_merge_request_errors! in lib/api/helpers/merge_requests_helpers.rb, the validations in app/models/merge_request.rb and MergeRequests::CreateService), read on October 24, 2026.
The answers
- 409
{"message":["Another open merge request already exists for this source branch: !42"]}: a merge request from the same branch of the same project into the same target branch is still open, and its reference follows the colon. A draft counts, because it is open; one that is closed or merged does not. A merge request from the same branch into a different target branch is allowed. - 422
{"message":["You can't use same project/branch for source and target"]}: the source and the target are the same branch of the same project. - 400
{"message":{"source_branch":["does not exist"]}}(ortarget_branch): the project has no branch by that name. Usually the branch has not been pushed yet, or the name differs in case or spelling. - 400
{"message":{"source_branch":["is invalid"]}}: GitLab does not accept that name as a merge request branch. - 403
{"message":"403 Forbidden"}: your account may not create merge requests from this project, or into the target project (target_project_id, when you create one from a fork). GitLab's permissions page lists creating merge requests from the Developer role up, and says that in projects that accept contributions from external members, those users can create their own merge requests too. - 422
Source project is not a fork of the target project:target_project_idnames a project outside the source project's fork network.
A token without the api scope is refused with 403 too, but that answer says insufficient_scope; see which scope to add. A project path that does not exist, or that you cannot see, answers 404; see address or access.
Where it stands
curl -H "PRIVATE-TOKEN: your-token" "https://gitlab.com/api/v4/projects/group%2Fproject/merge_requests?state=opened&source_branch=feature&target_branch=main"
This lists the open merge requests from feature into main: the one the 409 names is among them. To see whether GitLab has the branch, …/projects/group%2Fproject/repository/branches/feature answers 404 when it does not. Use your own server's address instead of gitlab.com.
What to do
- 409: open the merge request it names and keep working there: pushing to the branch updates it. If you want a new one, close the old one first, or choose another target branch.
- 422 "same project/branch": choose a different target branch, usually the default branch.
- 400 "does not exist": push the branch (
git push -u origin feature), then create the merge request; check the spelling of both branch names. - 403: ask a maintainer for the Developer role, or fork the project and create the merge request from your fork.
In IntelliJ IDEA: "Failed to create merge request", "No changes between …", "Unable to create merge request from … to …" and "Commits will be pushed to a protected branch"
The New Merge Request tab of the GitLab support built into IntelliJ IDEA checks the two branches before you create, then sends the same POST /projects/:id/merge_requests as above. In the source (checked October 30, 2026; IntelliJ IDEA: GitLabMergeRequestCreateViewModel.kt, GitLabMergeRequestCreateStatusComponentFactory.kt, GitLabMergeRequestsApi.kt, GitSharedSettings.java):
- "Failed to create merge request" when GitLab refuses the request, whatever the reason. Details shows the message, so the answers above apply: 409, 422, 400 or 403.
- "Merge Request already exists" with View when an open merge request already goes from the same branch of the same project into the same target branch: the case GitLab refuses with 409.
- The three checks below show one line at a time, in this order, and none of them asks GitLab.
- "Unable to create merge request from main to origin/main" when the branch you would merge is your local branch of the same name that tracks the target branch: the commits are on your local copy of the target. Make a new branch from it and create the merge request from that.
- "No changes between 'origin/main' and 'feature'" when the source branch has no commits that are not in the target branch. IntelliJ IDEA counts them in your local repository (
git log origin/main..feature), so the answer is as of your last fetch. - "Commits will be pushed to a protected branch" when the source branch's name matches IntelliJ IDEA's own Git setting Protected branches (Settings | Version Control | Git;
masterandmainby default; with Load branch protection rules from GitHub on, GitHub's rules are added). It is not GitLab's protected branches.
GitLab merge requests in IntelliJ IDEA
Merge Request Inbox for GitLab, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, creates a merge request from the branch you are on. When GitLab does not have the branch yet, it offers to push it first; it does not accept the same branch as the target; and when GitLab answers 409, it says that a merge request for this branch is already open, with GitLab's words, which name it. For 403, it says that your role in the project or its settings may not let your account do it; other refusals in GitLab's words. Reading is free; creating, 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 (405, 409, 422) · GitLab approval refused (401, 409) · GitLab comment or thread refused (400, 403) · GitLab "insufficient_scope" · GitLab 401 "invalid_token" · GitLab 404 "Project Not Found" · GitLab rebase refused or failed (403, 409) · GitLab merge request list refused (400, 404) · GitLab merge request changes cut short ("1000+", too_large) · GitLab 429 "Retry later" (rate limits) · GitLab "compare_timeout": true (diff limits) · GitLab merge request plugins for IntelliJ IDEA, compared · 日本語