GitHub: "Pull Request is not mergeable" and "Head branch was modified"
When PUT /repos/OWNER/REPO/pulls/NUMBER/merge fails, GitHub's REST documentation names the statuses: 405 when the merge cannot be performed, 409 when you sent sha and the pull request's head no longer matches it, 403 when you may not do it, and 422 when the request fails validation or the endpoint has been spammed. GitHub's earlier API documentation showed the messages of the first two:
HTTP/1.1 405 Method Not Allowed
{"message": "Pull Request is not mergeable", "documentation_url": "…"}
HTTP/1.1 409 Conflict
{"message": "Head branch was modified. Review and try the merge again.", "documentation_url": "…"}
405 "Pull Request is not mergeable"
The message does not say why. These are the cases, from GitHub's documentation and from public reports:
- GitHub has not finished checking it. GitHub's documentation: when a pull request is created or changed, GitHub works out in a background job whether it can be merged, and
mergeableis null until the job is done. Public reports show the same message, from REST and from GraphQL, for a merge sent right after a push or a branch update, and the same pull request was mergeable a few seconds later. - It conflicts with the target branch.
mergeableis false. - The branch's rules are not met yet. A branch protection rule or ruleset asks for approving reviews, passing status checks, or a branch that is up to date with the target before the merge.
- It is a draft. A draft cannot be merged until it is marked ready for review.
Public reports also show 405 with Base branch was modified. Review and try the merge again. (the target branch moved): read the pull request again, then merge.
Where it stands
curl -H "Authorization: Bearer your-token" https://api.github.com/repos/OWNER/REPO/pulls/42
mergeable is true, false or null (still being worked out: read it again a moment later), and mergeable_state gives the state in a word, for example unknown. GraphQL documents the states: mergeable is MERGEABLE, CONFLICTING or UNKNOWN, and mergeStateStatus is one of these:
CLEAN: mergeable and the commit status passes.UNSTABLE: mergeable with a status that does not pass.HAS_HOOKS: mergeable with passing status and pre-receive hooks.BLOCKED: the merge is blocked.BEHIND: the head branch is out of date.DIRTY: the merge commit cannot be cleanly created.UNKNOWN: the state cannot be determined yet.
409 "Head branch was modified. Review and try the merge again."
You sent sha, the head you reviewed, and the branch has another head now. In public reports, a commit was pushed between reading the pull request and merging it: by a script's own step that brought the target branch in, or by a bot that updates dependencies. Sending the old sha again fails the same way. Read the pull request, look at the new commits, then merge with the new head.
The asynchronous merge API
GitHub's documentation now recommends PUT …/pulls/NUMBER/merge-async instead; the endpoint above does not support stacked pull requests or a merge queue. It answers 202 with an ID to fetch the result, 200 at once when the pull request is already merged or in a merge queue, 400 at once when it cannot be merged (closed, or still a draft), and 409 when another asynchronous merge request for it is already pending. Branch protection rules and rulesets are not checked at that first step.
What to do
- 405 right after a push: wait a few seconds, read the pull request until
mergeableis not null, then merge again. - 405 with conflicts: update the branch or resolve the conflicts in a clone and push.
- 405 from the branch's rules: get the reviews or the passing checks that the rules ask for, update the branch if it is behind, or turn on auto-merge so that GitHub merges once the rules are met.
- 409: review the new commits, then merge with the new head's
sha. - 403: the token or its account may not merge here; see "Resource not accessible by personal access token".
In IntelliJ IDEA: the buttons stay off, and a refused merge shows nothing
How the GitHub support built into IntelliJ IDEA merges a pull request, in its source (checked October 30, 2026; IntelliJ IDEA: GHPRReviewFlowViewModelImpl.kt, GHPRMergeabilityStateBuilder.kt, GHPullRequestMergeStateStatus.kt, GHPRDetailsServiceImpl.kt, GithubApiRequests.kt):
- Merge… and Squash and Merge… are on only while GitHub's merge state is
CLEAN,HAS_HOOKSorUNSTABLE(for an administrator, when the target branch has a branch protection rule, alsoBEHINDorBLOCKED), so never while it isUNKNOWN,DIRTYorDRAFT; Rebase is on only when GitHub says the pull request can be rebased. Each also needs the method to be allowed in the repository, write permission, and, when the target branch has a branch protection rule, that you can push to it. - It merges with the REST endpoint above,
PUT /repos/OWNER/REPO/pulls/NUMBER/merge, not the asynchronous one, and sends the head it last loaded assha: a commit pushed since then gets the 409 above. Merge… and Squash and Merge… first ask for the commit message. - When GitHub refuses the merge, with a 405, a 409 or anything else, nothing appears on screen: the source writes the error to the IDE's log, and showing it is marked there as still to do. The pull request is then loaded again, so the buttons follow its new state. For the reason, read the pull request with the
curlabove.
GitHub pull requests in IntelliJ IDEA
Pull Request Inbox for GitHub, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, shows a pull request's merge checks before you merge, with the ones that block the merge first: approvals, requested changes, checks, conflicts, the target branch's rules not met yet, new commits on the target branch that the rules ask for, a draft, and whether your account may merge; while GitHub is still working it out, it says so. It merges the head commit you had on screen. When GitHub refuses, it says so: for 405, that GitHub cannot merge it now, with GitHub's words, and to see the merge checks; for 409, that the branch changed and to refresh. It can also turn on auto-merge and update the branch. The review inbox, diffs and conversations are free; approving, commenting and merging are Pro (US$1.50 a month, with a 30-day trial).
GitHub is a trademark of GitHub, Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by GitHub, Inc. or JetBrains.
More: GitHub review refused (422) · GitHub search 422 "Validation Failed" · 401 "Bad credentials" · "Resource not accessible by personal access token" · "Resource protected by organization SAML enforcement" · "API rate limit exceeded" · GitHub diff 406 "too_large", 3,000 files · GitHub line comment 422 "must be part of the diff" · GitHub branch update refused (422) · GitHub pull request not created (422, 403) · GitHub auto-merge refused · GitHub draft, ready for review or close refused · GitHub conversation not resolved · GitHub checks not shown (check runs 403) · GitHub file contents not read · GitHub compare refused (404, 422) · GitHub comment or reply refused (403 locked, archived) · GitHub merge method not allowed (405) · GitHub branch not found (404, 301) · GitHub Enterprise Server not reached · GitHub review request not shown · GitHub pull request list incomplete · GitHub 404 Not Found, renamed repositories (301, 307) · GitHub line comment outdated or not on the diff · GitHub pull requests not updating, notifications late · GitHub suggested change cannot be applied · GitHub required check stuck at "Expected" · GitHub code owner review required · GitHub merge blocked by unresolved conversations · GitHub merge blocked by unsigned commits · GitHub branch that merges through a merge queue · GitHub merge waiting for an approval of the most recent push · GitHub merge waiting for code scanning results · GitHub merge waiting for code quality results · GitHub merge blocked by a code coverage threshold · GitHub merge blocked by license compliance results · GitHub branch locked or its updates restricted · GitHub branch not deleted after merging · GitHub merge waiting for a team's approval (Required reviewers) · GitHub merge blocked by secret scanning alerts · GitHub stacked pull request not merging · GitHub push blocked by push rules · GitHub merge blocked by commit metadata rules · GitHub force push blocked · GitHub issue not closed by a merged pull request · GitHub pull request not checked out locally · GitHub pull request has merge conflicts · GitHub changes requested and dismissing a review · GitHub co-author not credited for a commit · GitHub dependency review check failed · GitHub Dependabot not rebasing its pull request · GitHub fork not syncing with upstream · GitHub pull request base branch not changing · GitHub pull request not reverting · GitHub pull request template not showing · GitHub pull request labels or assignees not added · GitHub pull request not closing or reopening · GitHub push blocked by push protection · GitHub pull request comment hidden · GitHub pull request blocked until deployments succeed · GitHub team review request replaced by members · GitHub pull request file no longer marked Viewed · GitHub pull request marked merged without being merged · GitHub Copilot review does not count as an approval · GitHub checks not running on a pull request a workflow created · GitHub Update branch button not shown on a pull request · GitHub checks failing on a Dependabot pull request · GitHub checks failing on a pull request from a fork · GitHub checks skipped by [skip ci] in a commit message · GitHub checks gone after the retention period · GitHub code review limits in a public repository · GitHub pull requests turned off or limited in a repository · GitHub checks run on every pull request in a stack · GitHub pull request showing commits already squash merged · GitHub pull request not showing a file diff · GitHub push to a pull request branch from a fork refused · GitHub check cancelled on a pull request · GitHub Rebase and merge not available · GitHub merge commit message not what you expected · GitHub pull request shows every line changed · GitHub API request timed out · GitHub pull request image or document diff not shown · GitHub review request refused (422) · GitHub pull request from Copilot: checks not running, approval not counted · GitHub push refused: GH006 and GH013 on a protected branch · GitHub "At least 1 approving review is required", approvals that do not count · GitHub pull request plugins for IntelliJ IDEA, compared · 日本語