Stack merge blocked despite all requirements met: evaluator divergence, phantom queued state, latency #404
thekidnamedkd
started this conversation in
Feedback
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Environment: gh-stack v0.1.0, gh CLI, private repo, protected default branch (required CODEOWNER review + "require approval from someone other than the last pusher" + linear-history requirement). 5-layer stack, merge-commit strategy.
Worked through a full lifecycle (create → review fixes → merge) and hit a cluster of issues, most pointing at the stack-merge rule evaluator and stuck internal state.
1. Per-PR evaluator and stack-merge evaluator disagree (main blocker)
Every remaining layer reported, individually:
mergeStateStatus=CLEAN,reviewDecision=APPROVED, fresh CODEOWNER approvals on the exact current head SHAs, linear history with the base, checks green, reviewer ≠ last pusher, signed commits. Yetgh stack mergeand the UI "Merge stack" both failed repeatedly with:The per-PR API said everything was satisfied; the atomic stack merge insisted the same approvals were stale/missing. Verified the approvals were dated after the base last moved and were on the current heads.
2. UI shows "Ready" / enables "Merge stack" but the merge auto-disables
The stack map showed all layers "Ready" and the green "Merge stack" button enabled. Clicking it produced repeated timeline entries: "stack merge was automatically disabled — Pull Request is not mergeable." The optimistic UI state did not match what the merge path would accept.
3. Phantom "queued for merge / auto-merge" state, invisible to the API
gh stack unstackrefused: "Some pull requests are queued for merge or have auto-merge enabled." But every PR hadautoMergeRequest=nullandmergeQueueEntry=nullvia GraphQL, and the repo has no merge queue configured.gh pr merge --disable-autoon each PR cleared this invisible state and changed the unstack error.4. unstack is all-or-nothing with merged members; dissolves only after latency
With the bottom PRs already merged,
gh stack unstackerrored "PRs #X, #Y cannot be removed from this stack" (the merged ones) rather than removing just the open PRs. Docs describe website unstack as removing only open/draft/closed and keeping merged. Eventually the server stack DID dissolve (GraphQLpullRequest.stack→ null) whilegh stack viewstill showed the stack locally — stale local tracking after a server-side change.5. Severe recomputation latency throughout
mergeable/reviewDecision/mergeStateStatus/ retarget all lagged heavily and oscillated (UNKNOWN ↔ BLOCKED ↔ CLEAN) for minutes, making it very hard to distinguish a real gate from a transient. Several operations took a while to reflect server-side.6. Base retarget dismisses CODEOWNER approval per layer
Merging a lower PR retargets the next to the trunk; the retarget dismissed the CODEOWNER approval, requiring a fresh re-approval for every layer in turn. Combined with #1 and #5, this made the end-of-stack merge a repeated re-approval loop.
Net
The only path through was: disable auto-merge (clear the phantom state) → server stack dissolved (after latency) → PRs became normal → merge bottom-up individually with
gh pr merge, retargeting each to the trunk. The atomic stack merge never succeeded despite all documented requirements being provably met at the per-PR level.All reactions