A teammate pinged me: their PR had all checks passing, review approved, auto-merge enabled. But it just sat there. No merge. No error. Nothing.
Took about 15 minutes of API poking to figure out what happened. The answer is embarrassing (for GitHub, not for us).
The symptom
PR shows “All checks have passed.” Branch protection requirements met. Auto-merge enabled. Status: BLOCKED.
No toast, no banner, no indication of why it’s blocked. Just… blocked. Same UI state as “a required check is failing.” Completely indistinguishable.
The cause
Our monorepo only allows squash merge:
{
"allow_merge_commit": false,
"allow_squash_merge": true,
"allow_rebase_merge": false
}
The PR had auto-merge enabled with mergeMethod: "MERGE" (merge commit). GitHub accepted this configuration without complaint. Then it just… never merged. Like ordering delivery to an address the restaurant doesn’t deliver to. The order sits there pending forever. Never rejected, never arrives.
How to diagnose
Three API calls, in order:
1. Check the PR’s merge state and auto-merge config:
gh pr view 12345 --json mergeStateStatus,mergeable,autoMergeRequest
Output:
{
"mergeStateStatus": "BLOCKED",
"mergeable": "MERGEABLE",
"autoMergeRequest": {
"mergeMethod": "MERGE"
}
}
That mergeMethod: "MERGE" next to mergeStateStatus: "BLOCKED" is your clue.
2. Try the merge via API to get the actual error:
gh api repos/OWNER/REPO/pulls/12345/merge \
--method PUT --field merge_method=merge
Response:
Merge commits are not allowed on this repository. (HTTP 405)
There it is. The error GitHub never shows you in the UI.
3. Confirm the repo’s allowed merge methods:
gh api repos/OWNER/REPO --jq '{allow_merge_commit, allow_squash_merge, allow_rebase_merge}'
The fix
Disable auto-merge, re-enable it with squash. Or just manually squash-merge.
gh pr merge 12345 --squash --auto
Why this is annoying
GitHub’s GraphQL enablePullRequestAutoMerge mutation happily accepts any mergeMethod, even one the repo doesn’t allow. No validation error. No warning. It stores the invalid config and then the merge actor silently fails every time it tries to execute.
The mergeStateStatus field returns BLOCKED with no additional context. Same value you’d see for a missing required review or a failing check. There’s no mergeBlockReason or equivalent that says “hey, the merge method is disallowed.”
The only way to get a useful error message is to attempt the merge yourself via the REST API and read the 405 response. That’s… not great developer experience.
The general pattern
When GitHub auto-merge is stuck on BLOCKED despite all checks passing:
gh pr view --json autoMergeRequestto check the configured merge methodgh api repos/OWNER/REPO --jq '{allow_merge_commit, allow_squash_merge, allow_rebase_merge}'to check what’s actually allowed- If they don’t match, re-enable auto-merge with the correct method