Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Link a pull request URL for which GitHub already returns
NOT_FOUNDwhen using the server's credential. The repository can be deleted, or private and inaccessible to the server's GitHub credential. My links point to private repositories that my credential cannot access. The link never gets a snapshot. - Settle the thread.
- Leave the server running. No client needs to be open.
- Count the
getPullRequestSummaryspans underPullRequestSyncReactor.sweepinserver.trace.ndjson.
The access failure itself may be expected. The bug is that the sync retries the failed read every minute indefinitely, even on settled threads.
Expected behavior
Settled threads do not trigger periodic reads of their linked pull requests. The user guide says "A settled thread's reviews stop refreshing until you unsettle it." On unsettled threads, the sync retries pull requests that GitHub cannot find every 15 minutes, like closed pull requests.
Actual behavior
The sync reads each of these pull requests on every one-minute sweep indefinitely, including those on settled threads. On my machine, 9 such links, all on settled threads, made 10 failed GraphQL requests a minute: one failed batch and 9 single reads. In my current trace files, 52 sweeps made 10 failed reads each. All 520 reads failed. These failed reads accounted for 520 of the 538 GraphQL requests the server sent during that time. My earlier measurement, with 38 such links across about 150 threads, counted 1,240 failed reads in 36 minutes. The account ran out of GraphQL quota, and other gh commands that use GraphQL failed until the reset.
Three paths in apps/server/src/orchestration-v2/PullRequestSyncReactor.ts keep these links due:
isDuereturns true for any link without a snapshot before it filters out settled threads. fix(server): settled threads stop polling their pull requests #16762 left this check above the settled filter.syncGroupclears arequestedkey only after a successful read. After a not-found read, the key stays requested. Every later sweep reads the pull request again, even if the thread is settled.- Each
thread.pull-request-syncedevent requests every link on the thread that has no snapshot. A sync of any other link on that thread requests the unreadable ones again.
The GitHub batch fallback adds to the cost. One NOT_FOUND alias causes the whole batched summary query to fail. GitHubPullRequestApi then reads each pull request in that batch separately, including readable ones.
I have a fix that changes only the reactor and includes regression tests. It applies the no-snapshot rule only to unsettled threads. The fix treats a not-found answer as a finished read and clears the request. On unsettled threads, periodic sweeps retry the pull request every 15 minutes. Another link's sync no longer requests the missing pull request again. A reader's refresh still does. A PR with this fix follows this issue.
The reactor's polling logic is the same on main at c77a7b7. A dev server on main with a copy of my data makes the same 10 failed requests per sweep.
Related:
- fix(server): settled threads stop polling their pull requests #16762 stopped periodic reads for settled threads but kept the no-snapshot check first.
- A comment on Unrecognised GitHub Enterprise host re-probes fj, tea and glab once per project on every sweep #12060 reports that links without a snapshot are "due on every sweep". The triage on that issue fixes how unknown Git hosts are probed. It does not change this sweep.
- [Bug]: PR detail/activity is re-fetched for every displayed PR on each focus, visibility change and 5-minute tick (merged PRs included), exhausting the GitHub GraphQL quota #13496 and Thread PR discovery and settlement sweeps run every minute without client demand, and their caches expire before the next sweep #11220 cover other polling paths.
- perf: trim application startup and deferred runtime work #17609 (open) changes the same event handler and adds a request for unsynced sibling links when a link syncs.
Investigated and filed with Claude Code (Claude Opus 5.5).
Impact
Major degradation or frequent failure
Version or commit
0.0.46-nightly.20261008.2833
Environment
macOS 27.0, T3 Code (Nightly) desktop app, GitHub through the app's GitHub API transport.
Logs or stack traces
# Summary reads under PullRequestSyncReactor.sweep, from server.trace.ndjson
sweep 10:41 GitHubApiNotFoundError 10
sweep 10:42 GitHubApiNotFoundError 10
sweep 10:43 GitHubApiNotFoundError 10
# 52 of the 53 sweeps from 08:56 to 10:43 UTC made 10 failed reads each: 520 reads, 0 successes.
WARN pull request sync skipped
{ count: 9, reason: 'Pull request operation summary failed: GitHub could not find the requested resource, or the credential cannot see it.' }Screenshots, recordings, or supporting files
No response
Workaround
Unlink the unreadable pull requests, or archive their threads. The sweep skips unlinked pull requests and archived threads.
Activity
aram-eskandari commentedon Oct 19, 2026
Same issue here on T3 Code (Beta) 0.1.0, macOS, on a much larger scale.
Setup: three github.com accounts logged into
gh. Threads had PRs linked from repos owned by the two non-active accounts, which the active credential can't see (also #14123). 112 links across ~25 threads (open, settled and older ones) never got a snapshot.What I measured (
server.trace.ndjson, 30-minute window):getPullRequestSummaryGraphQL calls, all underPullRequestSyncReactor.sweep→syncGroup→PullRequestService.persistedRead→PullRequestReadCache.getGitHub could not find the requested resource, or the credential cannot see itghand everything else on the same account then hitAPI rate limit exceededfor GraphQLWorkaround: unlinking the 112 links (via the
unlink_pull_requestMCP tool, passingthreadId) took it from ~185 calls/min to 0–2 calls/min within two minutes.They come back whenever an agent links a new PR in one of those repos, so it would help to remember NOT_FOUND results per link with a long backoff, as the issue suggests, or to pick the credential per repo owner (#14123).
juliusmarminge commentedon Oct 22, 2026
Reproduced on Linux with the web dev server at 70e5e384da. Linked a nonexistent GitHub pull request, received
GitHubApiNotFoundError, then settled its thread. The reactor retried at 22:52, 22:53, and 22:54 UTC; the last attempt occurred after closing the browser.Runtime transcript. Regression tests also reproduce the settled-thread retries, missing-result backoff, and sibling re-request paths.
PolarBearEs commentedon Oct 30, 2026
Same on Bitbucket Cloud (0.1.6-nightly.20261030.3917, Linux).
I had 12 linked Bitbucket pull requests, 11 of them on settled threads, and none had a snapshot. Every one-minute sweep reread all 12:
isDuereturnstruefor a missing snapshot before it checks whether the thread is settled. The reads failed with 404 first, then 429.Each Bitbucket read is 5 requests (#27578), so that came to about 3,600 requests an hour, against Bitbucket's limit of 1,000. The host stayed paused, and while it was paused I couldn't open pull requests either (#27579). Unlinking the pull requests stopped it.