github / github/gh-stack

`submit` loops forever after a failed stack delete: stale `pending_submit` modify state has no supported way out

Đang mở
#433 1 bình luận 1 reaction 0 người được giao Xem trên GitHub
bug topic: cli - submit
Ngôn ngữ chính
Go
Star
1.5k
Fork
70
Merge trung bình
1 ngày 8 giờ
Pull request đã merge (30 ngày)
7

Mô tả

## Summary

After a `gh stack submit` fails with the HTTP 422 from #428, the modify session state left in `.git/gh-stack-modify-state` keeps pointing at the old stack, so **every subsequent `gh stack submit` retries the same impossible delete**. The error tells you to "Run `gh stack submit` again to retry", but the retry can never succeed, and no CLI command clears the state. The only escape is deleting an internal file by hand.

This is separate from #428: that issue is about the 422 itself. This one is about being unable to recover from it.

Compounding it, the failed `unstack` is **partially applied** — the open PRs really are removed from the stack on GitHub — so the repository is left in a state that matches neither the local metadata nor the pre-submit state.

## Reproduction

Starting from a submitted stack (`#10`) whose bottom layers are merged — `#101`, `#102` merged; `#103 → #104 → #105` open:

1. `gh stack modify`, insert a new branch mid-stack (between `#103` and `#104`), `Ctrl+S`. The modify applies locally.
2. `gh stack submit`, answer `Yes` to "Overwrite the existing stack on GitHub?"

```
Checking stack state...
Skipping 2 merged branches
? The local stack has been modified. Overwrite the existing stack on GitHub? Yes
⚠ Failed to delete existing stack: HTTP 422: Pull requests #101, #102 cannot be removed from this stack (.../stacks/10/unstack)
Run `gh stack submit` again to retry
```

3. Run `gh stack submit` again — and again. Identical output every time.

### The state that causes it

`.git/gh-stack-modify-state`:

```json
{
"schema_version": 1,
"phase": "pending_submit",
"prior_remote_stack_id": "900001",
...
}
```

`900001` is the internal id of stack `#10`. Every `submit` reads `prior_remote_stack_id` from this file and re-attempts the delete, which GitHub will never allow while the stack contains merged PRs.

Editing `.git/gh-stack` (removing the merged branch entries) does **not** help — the modify-state file is a second, independent store, and it is the one `submit` consults.

### The partial unstack

After the first failed submit, GitHub's side had already changed:

```
$ gh api repos/OWNER/REPO/stacks
stack 10 open=false prs=[101, 102]
```

The open PRs `#103`, `#104`, `#105` were successfully removed and now belong to no stack at all; only the two merged PRs remain. So `unstack` removed what it could and reported total failure. Local metadata still described all five.

## Available exits, none of them good

- `gh stack submit` — loops forever, as above.
- `gh stack modify --abort` — would discard the completed mid-stack insertion, which is the work the user is trying to keep.
- `gh stack unstack 10` — cannot help; GitHub refuses to remove the merged PRs, which is the original 422.
- Editing `.git/gh-stack` — no effect, wrong file.
- **`rm .git/gh-stack-modify-state`** — the only thing that works.

After removing that file, `gh stack submit` succeeded immediately and did the right thing:

```
✓ Created PR #106 for
✓ Updated base branch for PR #104 to
✓ Stack created on GitHub with 4 PRs (stack #11)
```

Which shows the operation was viable all along — only the stale `prior_remote_stack_id` was blocking it.

## Expected behavior

1. When the delete fails with a 422 that **cannot** succeed on retry (merged PRs can never be removed from a stack), don't advise retrying. Fall back to creating a new stack, or say plainly that the old stack cannot be dissolved and offer that as a choice.
2. Provide a supported way to clear a stuck `pending_submit` modify state without discarding the applied modify — e.g. a counterpart to `gh stack modify --abort` such as `--forget`/`--done` that drops the session but keeps the local restructuring.
3. Reconcile the partial unstack: if some PRs were removed and others refused, report that, and update local metadata to match what actually happened on the server.

## Related

- #428 — the 422 itself (new bottom branch after a merge). Same root cause, different trigger; this report covers the unrecoverable state afterwards.
- #382 — mid-stack insertion strands merged PRs.
- #372 — `unstack` reporting generic errors instead of the real API rejection.

## Environment

- `gh` 2.97.0
- `gh-stack` v0.1.0
- git 2.50.1 (Apple Git-155)
- macOS 26.6, darwin/arm64

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với phần xử lý `gh stack submit` cho `.git/gh-stack-modify-state`, sau đó so sánh các luồng `gh stack modify --abort` và `gh stack unstack`. Tái hiện thao tác xóa bị lỗi với bố cục đã được ghi lại gồm một PR đã merge và một PR đang mở. Hoàn tất khi một unstack từng phần bị lỗi được báo cáo và đối soát, đồng thời người dùng có một phương thức khôi phục được hỗ trợ để giữ lại thay đổi đã áp dụng thay vì thử lại trạng thái `pending_submit` đã cũ.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
github, go
Lĩnh vực
cli
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.