[Bug]: Sidebar and composer PR badges show total linked count with open status for mixed states#15702

opened26d agobyAashx-j

Before submitting

  • Searched existing issues and did not find a duplicate.
  • Included enough detail to reproduce or investigate the problem.

Area

apps/web. Affects the thread sidebar and the toolbar below the message composer, both of which use the same PR badge component.

Steps to reproduce

  1. Link multiple unrelated PRs to one thread, including both open and closed PRs.
  2. For the reported example, link closed PRs #15694, #15692, and #15680, and their open replacements #15697, #15698, and #15699.
  3. Inspect the PR badge in the thread sidebar and below the message composer.
  4. Hover over the thread to compare the badge with the individual PR statuses.

The original PRs were automatically closed after the source fork was accidentally deleted. Their replacements were created with the same commits. Both sets were linked to this thread during recovery. Deleting a fork is not required to reproduce the badge logic; the relevant condition is a mixture of open and closed linked PRs.

Expected behavior

The badge should distinguish the total linked count from the open count. For example, show 3 open · 3 closed, or a neutral 6 PRs badge with the breakdown in the tooltip. The exact presentation is a product decision.

Actual behavior

Both locations show a green open-PR icon followed by +6, which reads as six open PRs. The tooltip correctly shows three green open icons and three red closed icons. The individual PR states are correct; the aggregate badge is misleading.

Impact

Minor bug or occasional failure. Users cannot reliably read the number of open PRs from the badge when a thread includes closed PRs.

Version or commit

Source inspected at 4ee6bfd50ef4a089440d5c3662db2298da9cc50e. The exact installed app build shown in the reporter's screenshots was not confirmed.

Supporting evidence

The reporter supplied screenshots of both affected locations. No browser automation or runtime changes were performed during investigation.

Workaround

Open the linked PR list or hover over the thread and inspect each PR's individual status.

Note

Grok responding on behalf of Julius.

Triage

Thanks for the clear write-up and the code links, @ashx-j. Laying out the mixed-state recovery scenario made this easy to follow.

What I found

Confirmed on main at 4ee6bfd. I didn't find another issue for this.

  • One state for all links. resolveThreadPullRequestBadge folds every visible link into a single state:
    • draft only when every link is an open draft
    • open when any link is open
    • merged only when every link is merged
    • closed otherwise
  • Links without a snapshot are counted as open.
  • What the badge shows. For unrelated links (not one stack), the badge pairs that state's icon and color with +N, where N is the total visible count (ThreadStatusIndicators.tsx). The sidebar and the composer toolbar both render that control, while the hover list draws each link individually.
  • Where the rule came from. It was introduced in #11180, and the mixed open/closed case is covered in packages/shared/src/threadPullRequests.test.ts, apps/web/src/components/ThreadStatusIndicators.test.ts, and apps/mobile/src/state/use-thread-pr.test.ts.
  • Mobile behaves the same. It uses the same aggregate in presentThreadLinkedPullRequests, so the thread list there shows an emerald +6 with the accessible name "6 linked pull requests, overall open".
  • Stacks are separate. A single stack uses the layers glyph and layer count instead, so this report is about the unrelated-links path.

Likely fix area

Options in resolveThreadPullRequestBadge and the badge control, applied on web and mobile alike:

  • a split count, such as 3 open · 3 closed
  • a neutral total, such as 6 PRs, with the breakdown in the tooltip
  • counting only open links next to the open icon

Whichever one is chosen, the existing web and mobile tests would need to change with it.

A maintainer will decide on the fix direction.

Reproduced on current main 3b95e7831b in Chromium on Linux, using the real web dev app with an isolated database. Six unrelated links with three open and three closed snapshots show a green open icon and +6 in the sidebar, with the accessible label “overall open”. The original replacement PRs are now closed, so the reproduction uses synthetic links preserving the reported states. No duplicate found in the open-issue search.

browser-screenshot-localhost-mvj6eokv-3ad3d8d5.png