Repository navigation
PR auto-merge always fails: GraphQL mutations use non-existent MergeMethod type #206
Description
Problem
With PR_AUTO_MERGE=true (introduced in #185), auto-merge never succeeds. GitHub rejects both mutations before execution because they declare the variable with a type that does not exist in its GraphQL schema:
auto-merge failed: GitHub GraphQL request was rejected: MergeMethod isn't a defined input type (on $mergeMethod)
Observed in a real run (agent-simple-rpg-engine, issue #24, attempt 2026-10-11T14:53:26.424648Z, outcome complete), event auto_merge_failed in agent_output.json at 2026-10-11T15:00:34Z. The PR (lbacik/simple-rpg-engine#45) was opened but had to be merged by hand.
Because _maybe_auto_merge never raises, the attempt still ends complete and the failure only appears as a WARNING event and in the result comment.
Root cause
simple_coding_agent/github_tracker.py declares $mergeMethod: MergeMethod! in both:
enable_auto_merge(line ~550,EnableAutoMergemutation)merge_pull_request(line ~573,MergePullRequestmutation)
GitHub's enum is named PullRequestMergeMethod (values MERGE, SQUASH, REBASE). Verified by introspection:
gh api graphql -f query='{ a: __type(name:"MergeMethod"){name} b: __type(name:"PullRequestMergeMethod"){name enumValues{name}} }'
# => {"data":{"a":null,"b":{"name":"PullRequestMergeMethod","enumValues":[{"name":"MERGE"},{"name":"SQUASH"},{"name":"REBASE"}]}}}
The existing tests in tests/test_github_tracker.py assert only on transport.variables and never check the query text, so the bad type went unnoticed.
Proposed fix
- mutation EnableAutoMerge($pullRequestId: ID!, $mergeMethod: MergeMethod!) {
+ mutation EnableAutoMerge($pullRequestId: ID!, $mergeMethod: PullRequestMergeMethod!) {- mutation MergePullRequest($pullRequestId: ID!, $mergeMethod: MergeMethod!) {
+ mutation MergePullRequest($pullRequestId: ID!, $mergeMethod: PullRequestMergeMethod!) {Also update the _graphql_merge_method docstring (line ~737), which refers to GitHub's MergeMethod enum.
Tests
- Add assertions that both mutations declare
$mergeMethod: PullRequestMergeMethod!(e.g. checktransport.queries[0]), so a wrong type name fails a unit test rather than a live run.
Related, to verify while fixing: direct-merge fallback on unprotected branches
When the base branch has no protection rule and the PR is already mergeable, GitHub typically refuses enablePullRequestAutoMerge with a message like Pull request is in clean status rather than one containing mergeable. _is_already_mergeable (simple_coding_agent/publication.py ~438) matches only on "mergeable", so in that case the code would skip _merge_directly and report auto_merge_failed again, just with a different message.
The target repo above (lbacik/simple-rpg-engine, main not protected, allow_auto_merge: true) is exactly this case. This hasn't been verified live because the type error fails first. Suggested change: also treat clean status (and possibly unstable status) as "mergeable now", and add a unit test that uses that error text.
Acceptance criteria
- Both mutations use
PullRequestMergeMethod!; a unit test pins the declared type. - On a repo with an unprotected base branch, a
completeattempt withPR_AUTO_MERGE=trueends with the PR merged (pull_request_mergedevent), notauto_merge_failed. - On a repo with branch protection and required checks, auto-merge is enabled (
auto_merge_enabledevent).
🤖 Generated with Claude Code
Activity
lbacik commentedon Oct 11, 2026
Agent Brief
Category: bug
Summary: Auto-merge GraphQL mutations declare a non-existent
MergeMethodtype, and the direct-merge fallback misses GitHub's "clean status" refusalCurrent behavior:
With
PR_AUTO_MERGEenabled, every merge attempt is rejected by GitHub before execution:MergeMethod isn't a defined input type (on $mergeMethod). Both GitHub tracker operations that take a merge method —enable_auto_merge()(theenablePullRequestAutoMergemutation) andmerge_pull_request()(themergePullRequestmutation) — declare$mergeMethod: MergeMethod!. GitHub's enum is actuallyPullRequestMergeMethod(valuesMERGE,SQUASH,REBASE; confirmed by schema introspection during triage). Existing unit tests only assert on the GraphQL variables, never on the declared variable type, so they pass while every live call fails. The attempt still endscomplete, with anauto_merge_failedWARNING event andauto-merge failed: …in the result comment.Once the type is fixed, a second defect surfaces: when the base branch has no protection rule and the PR is already mergeable, GitHub refuses
enablePullRequestAutoMergewith a message likePull request is in clean status. The "already mergeable" classifier used by the publication auto-merge step (_is_already_mergeable) only matches the substringmergeable, so this refusal falls through toauto_merge_failedinstead of the direct-merge fallback. (Not yet observed live — the type error fails first.)Desired behavior:
$mergeMethod: PullRequestMergeMethod!. The helper that maps the operator merge method (_graphql_merge_method) and its docstring refer toPullRequestMergeMethod._merge_directlypath →pull_request_mergedevent, resultmerged). This includes refusals whose text says the PR is inclean statusorunstable status(case-insensitive), as well as the existingalready mergeablewording.CONTEXT.mdis unchanged: native auto-merge first, a merge failure never raises and never changes thecompleteoutcome.Key interfaces:
GitHubGraphQLTransport.enable_auto_merge(repository, pull_request, merge_method)and.merge_pull_request(...): only the declared GraphQL variable type changes; signatures and variables stay the same._is_already_mergeable(error) -> boolin the publication module: widen what counts as "mergeable now".Acceptance criteria:
enable_auto_mergedeclares$mergeMethod: PullRequestMergeMethod!(e.g. viatransport.queries[0]), and fails if the type isMergeMethod.merge_pull_request.MergeMethod.enable_auto_mergeraises an error containingPull request is in clean status→merge_pull_requestis called with the configured method, apull_request_mergedevent is logged, and the merge result ismerged(notauto-merge failed).unstable status.auto_merge_enabled;already mergeable→ direct merge; an unrelated error →auto_merge_failedwith the attempt stillcomplete.Out of scope:
lbacik/simple-rpg-engine→pull_request_merged; protected repo with required checks →auto_merge_enabled). The maintainer will do this after merge.mergeStateStatusinstead of matching error text.PR_AUTO_MERGE/PR_MERGE_METHODconfiguration, theagent-auto-mergelabel opt-in, or ADR 0004.lbacik commentedon Oct 11, 2026
Agent Attempt Result: complete
Branch: agent/issue-206
PR: #207
Evidence
UV_PROJECT_ENVIRONMENT=/home/agent/venv-py311 uv run --python 3.11 --extra dev ruff check && UV_PROJECT_ENVIRONMENT=/home/agent/venv-py311 uv run --python 3.11 --extra dev pytest && UV_PROJECT_ENVIRONMENT=/home/agent/venv-py313 uv run --python 3.13 --extra dev pytest→ exit code 0Details
Claude SDK completed the implementation workflow.