Desktop Code tab: 'Create PR' panel surfaces stale rows for deleted branches and meaningless self-PR (main ← main)
Surface
Claude Desktop app, Code tab (not the terminal/TUI). The "Create PR" panel rendered at the bottom of an assistant turn — the per-repo rows with +X -Y diff stats and a Create PR button.
Two distinct bugs in the same panel
Bug 1 — main ← main self-PR row is shown at all
When the assistant commits directly to main in a repo (e.g. a doc-only / cockpit repo with a direct-push workflow), the panel renders:
[repo-name] main ← main +305 -0 Create PR
Source branch == target branch. A self-PR is never valid; clicking Create PR would either no-op or error. This row should be suppressed entirely. The +305 -0 is correctly the diff produced this turn, but the affordance is meaningless on a direct-push repo.
Bug 2 — Stale-branch row persists after the branch is deleted in-session
If, earlier in the same session, the assistant did:
git push origin feat/SOME-BRANCH- (PR opened, admin-merged on GitHub, remote branch deleted by GitHub's "delete branch on merge")
- Later in the same session,
git fetch --prune+git branch -D feat/SOME-BRANCHto clean up
… the panel keeps showing:
[repo-name] main ← feat/SOME-BRANCH +305 -0 Create PR
The local branch is gone (git branch confirms), the remote ref is gone (git ls-remote confirms), the PR was already merged (visible on GitHub) — but the panel doesn't re-poll, so it offers a Create PR shortcut for a branch that no longer exists anywhere. Clicking would error.
Reproduction (combined)
# Multi-repo session — assistant operates on two repos with different conventions
mkdir -p /tmp/repo-direct /tmp/repo-pr
cd /tmp/repo-direct && git init && touch README.md && git add . && git commit -m init && git remote add origin <URL>
cd /tmp/repo-pr && git init && touch README.md && git add . && git commit -m init && git remote add origin <URL>
# Turn 1 (direct-push repo): commit a few hundred lines on main, push
cd /tmp/repo-direct && echo "..." > BIG.md && git add . && git commit -m "feat" && git push
# Turn 2 (PR repo): branch + push + admin-merge
cd /tmp/repo-pr && git checkout -b feat/X && echo "..." > BIG.md && git add . && git commit -m "feat" && git push -u origin feat/X
gh pr create --fill && gh pr merge --admin --squash --delete-branch
# Turn 3: clean up the local branch
cd /tmp/repo-pr && git checkout main && git pull && git branch -D feat/X
# Turn 4: any new assistant message
# -> Panel will show:
# [repo-direct] main ← main +N -0 Create PR
# [repo-pr] main ← feat/X +N -0 Create PR (feat/X no longer exists)
Verification that repo state is actually clean
[altius-ctx] on main | ahead=0 behind=0 uncommitted=0
[altius-infra] on main | ahead=0 behind=0 uncommitted=0
[altius-scheduler] on main | ahead=0 behind=0 uncommitted=0
[altius-experiments] on master | ahead=0 behind=0 uncommitted=0
Every repo: on the default branch, 0 ahead of remote, 0 behind, 0 tracked uncommitted files. Yet the panel renders rows that imply pending work, including for a branch that no longer exists. This is purely a panel-staleness issue — git state is consistent and pushed.
Why this matters (UX impact)
The phrase "Create PR" + a non-zero diff stat (+305 -0) reads as "you have unpushed work — click to ship it". A user reasonably interprets the panel as a pending-work indicator. When everything is actually pushed and merged, the user is left questioning whether something silently failed to commit/push. I had to drop into the shell and dump git status / git rev-list --count origin/main..HEAD across four repos to convince the user nothing was actually pending.
The panel becomes anti-informative: it generates fear of lost work where there is none.
Suggested fixes
- Suppress rows where source == target. A self-PR row has no valid action.
- Re-poll branch existence at render time (cheap:
git rev-parse --verify <branch>locally +git ls-remote --heads origin <branch>remote check). If neither exists, drop the row. - Distinguish "would-be PR" from "pending work". If the source branch's tip is already reachable from the target's remote tip (i.e. already merged), either suppress or label clearly ("already merged — nothing to PR") rather than offering a
Create PRbutton. - Suppress rows entirely for direct-push repos. A repo whose only branch is
maintrackingorigin/mainand whosemainis at parity withorigin/mainhas no PR-able state.
Environment
- Surface: Claude Desktop, Code tab (multi-repo session — root project + two nested git repos via submodule-like structure)
- Host OS: macOS (Darwin)
- Repos involved: 1 direct-push doc repo + 2 PR-workflow code repos
Related issues
- #55871 — Similar stale-state symptom (PR chip retains "Merged" badge + stale link after branch switch). Adjacent but a different surface (single chip vs. multi-row Create PR panel) and different state staleness (badge text vs. row existence).
- #53123 — Closed as DUPLICATE. Reported a stale-branch ghost row from a deleted worktree on Windows. Symptom matches Bug 2 here on macOS, with multi-repo + admin-merge as the trigger instead of worktree deletion.
- #45779 — Generic "UI displays stale state after session changes" tracking issue.
Workaround
Ignore the panel; /clear the session to flush it.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗