Skip to content

Stack view shows "not ready" / "unable to merge as a stack" on approved mergeable PRs (stale stack UI cache) #450

Description

@jdaison

Summary

The GitHub stack view (native stack feature, not CLI) shows "not ready" on some PRs in a 13-level stack, and displays "unable to merge as a stack" globally, even though every PR in the stack reports mergeable=MERGEABLE, mergeStateStatus=CLEAN (or UNSTABLE), reviewDecision=APPROVED, and all status checks passing via both REST and GraphQL APIs.

Stack structure (anonymized)

base-branch
 └── feat/base            → PR #1 (base: base-branch)           ← trunk base
  └── feat/layer-2        → PR #2 (base: feat/base)
   └── feat/layer-3       → PR #3 (base: feat/layer-2)
    └── feat/layer-4      → PR #4 (base: feat/layer-3)
     └── feat/layer-5     → PR #5 (base: feat/layer-4)
      └── feat/layer-6    → PR #6 (base: feat/layer-5)
       └── feat/layer-7   → PR #7 (base: feat/layer-6)
        └── feat/layer-8  → PR #8 (base: feat/layer-7)
         └── feat/layer-9 → PR #9 (base: feat/layer-8)
          └── feat/layer-A → PR #10 (base: feat/layer-9)
           └── feat/layer-B → PR #11 (base: feat/layer-A)
            └── feat/layer-C → PR #12 (base: feat/layer-B)
             └── feat/layer-D → PR #13 (base: feat/layer-C)

13 PRs in total. The bottom PR targets base-branch; each subsequent PR targets its predecessor's branch. All PRs are open, non-draft, created via gh stack submit.

Environment

  • gh 2.97.0
  • gh-stack v0.1.0
  • Repository: private, no branch protection, no repository rulesets, no merge queue, no CODEOWNERS.
  • "Dismiss stale pull request approvals when new commits are pushed": disabled.

Observed behavior

In the GitHub stack UI (native stack view)

Via the API (both REST and GraphQL, confirmed multiple times over several minutes)

Every PR in the stack (including #8 and #10) consistently reports:

Field Value
mergeable MERGEABLE
mergeStateStatus CLEAN (or UNSTABLE — only non-required checks pending like CodeRabbit)
reviewDecision APPROVED (multiple approvals from different reviewers)
statusCheckRollup.state SUCCESS
isDraft false
requested_reviewers [] (no pending reviewer requests)
No branch protection (none exists on any branch in the stack)
No repository rulesets (none exist)

GraphQL query used:

{
  repository(owner: "O", name: "R") {
    pullRequest(number: N) {
      mergeable
      mergeStateStatus
      reviewDecision
      isDraft
      statusCheckRollup { state }
    }
  }
}

Context about the "not ready" PRs (#8 and #10)

Attempted workaround: close + reopen the "not ready" PRs

We closed and reopened PR #8 (the first "not ready" PR in the stack) to force a full server-side recompute:

gh pr close 8 && gh pr reopen 8

Result:

  • The individual PR returned to mergeable=MERGEABLE, reviewDecision=APPROVED correctly.
  • The stack view took ~30 seconds to reload, but the state did not change: PR Docs site for stacks #8 remained "not ready", PR add alias command #9 remained "blocked downstack", and the global message stayed "unable to merge as a stack".

Close+reopen did not invalidate the stack view's cached state. The stack view appears to maintain its own independent cache that is not invalidated by PR state changes.

Expected behavior

Given that:

  1. All PRs are mergeable (no conflicts, MERGEABLE).
  2. All PRs are approved (APPROVED).
  3. All required status checks pass (SUCCESS).
  4. No branch protection, rulesets, CODEOWNERS, or merge queue block merging.
  5. Close+reopen did not help.

GitHub's native stack view should reflect the actual PR state and show all 13 PRs as "Ready", with the "Merge stack (13)" option enabled and functional. A stale cached state rendering the stack unmergeable is a blocking UX bug.

Related

  • Can't merge a stacked PR with no clear reason (all PRs show mergeable) #323 — "Can't merge a stacked PR with no clear reason (all PRs show mergeable)". Same class of bug: stack UI state differs from API state. In our case the stack never shows as mergeable at all (no attempt to merge fails — the UI never allows the attempt). We confirm the MERGEABLE/CLEAN/APPROVED symptom. Our close+reopen attempt did not resolve it, suggesting a different cache invalidation path.

Activity

  1. jdaison commented on Aug 18, 2026

    @jdaison
    Author

    I realized this issue is happening only to me, the author of the stack, and in every PR. Other teammates are watching everything ok

    Image Image
  2. jdaison commented on Aug 19, 2026

    @jdaison
    Author

    Additional context from our merge experience

    Some extra observations that may help reproduce or understand the limitation:

    Previous images showed different strategies for merging; the first image shows rebase and merge stack , and the second image shows squash and merge stack

    Stack had two PRs that needed to preserve full git history

    PRs #7 and #9 in this stack contained imported history from other repositories (940 and 879 commits respectively, including merge commits). These two PRs must keep all their original commits and SHAs to preserve provenance.

    The other 11 PRs were fine being squashed to 1 commit each.

    Problem: gh stack merge supports only one merge method

    gh stack merge --yes --squash would collapse the import history — not acceptable.
    gh stack merge --yes --rebase would try to replay 940+879 commits onto the base, rewriting SHAs and linearizing internal merge topology — also not acceptable.
    gh stack merge --yes --merge (merge commits for all) was the only viable option, but it forced merge commits even on the 11 PRs that ideally would have been rebase-merged for a linear first-parent history.

    What would help: a way to mark specific PRs in the stack for different merge methods, e.g.:

    gh stack mark --merge #7 --rebase #9  # hypothetical
    gh stack merge --respect-marks
    

    Or at minimum, allow --rebase + --merge as a mixed option where rebase is the default but a merge commit is used when the PR's branch is not a fast-forward descendant of its target.

    Stack linearity check was too strict after local branch restructuring

    After squashing the non-import branches locally (via git reset --soft + git commit), the stack was no longer linear: the import branches still pointed at their old parent histories, not the new squashed commits. gh stack merge refused with:

    Stack needs to be rebased: PR #8's branch is not a linear descendant of PR #7's branch.
    

    We had to fix this manually by:

    1. Rebase-fixing the child of each import branch (git rebase --onto <new-tip> <old-tip>)
    2. Merging the import branches into their new parents (git merge --no-ff) to make them descendants while preserving their history SHAs
    3. Force-pushing all 13 branches, then running gh stack merge --yes --merge

    This worked, but the manual re-parenting required deep git knowledge and trial-and-error. A gh stack repair command that automatically re-parents branches after local squashes would save a lot of effort.

    The original issue title (stack UI "not ready") was resolved by waiting

    The GitHub native stack view eventually resolved itself. The "not ready" / "unable to merge as a stack" messages were transient — after ~10-30 minutes per PR (the stack had 13 PRs with many commits), the native UI updated and allowed stacking. So that part was just a stale UI cache.

  3. added
    bugBug Reports
    topic: mergeabilityAuto-mergeability detection for stacked PRs is broken.
    on Aug 24, 2026
  4. 23Skidoo commented on Sep 10, 2026

    @23Skidoo

    Seeing this with just 2 PRs in a stack. UI tells me "Able to merge as a stack", then I press the "merge stack" button and it fails with "stack merge was automatically disabled 6 minutes ago. Pull Request is not mergeable".

  5. ccrawford4 commented on Sep 21, 2026

    @ccrawford4

    ++

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug Reportstopic: mergeabilityAuto-mergeability detection for stacked PRs is broken.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions