github / github/gh-stack

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

Offen
#450 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug topic: mergeability
Vorherrschende Sprache
Go
Sterne
1.5k
Forks
70
Ø Merge
1 T. 8 Std.
Gemergte PRs (30 T.)
7

Beschreibung

## 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)

- Bottom 7 PRs (#1–#7): show **"Ready"**
- PR #8: shows **"Not ready"** (no tooltip / reason shown)
- PR #9: shows **"Blocked downstack"**
- PR #10: shows **"Not ready"** (no tooltip / reason shown)
- PRs #11–#13: show **"Blocked downstack"**
- At the top: global message **"Unable to merge as a stack"**

### 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:
```graphql
{
repository(owner: "O", name: "R") {
pullRequest(number: N) {
mergeable
mergeStateStatus
reviewDecision
isDraft
statusCheckRollup { state }
}
}
}
```

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

- Both are **history-import PRs** — they contain 500+ commits each (preserved full history of the imported repositories), adding ~48k lines across 180+ files.
- The remaining PRs are smaller (single-digit to low-double-digit commits).
- All PRs (including #8 and #10) were created via the same `gh stack submit` flow, all with the same review/check configuration.
- The status checks on #8 and #10 all show **green/success**. Only CodeRabbit (not required) shows as not completed.

## 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 #8 remained "not ready", PR #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

- **#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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Es werden keine Repository-Dateien oder Tests genannt. Beginne damit, den 13 Ebenen umfassenden Stack in GitHubs nativer Stack-Ansicht zu reproduzieren, und vergleiche die dort angezeigte Bereitschaft mit den im Bericht aufgeführten REST- und GraphQL-Feldern; fertig ist es, wenn die UI die genehmigten, mergebaren PRs widerspiegelt und "Merge stack (13)" aktiviert.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
github
Bereich
frontend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.