fix(github): pull requests missing refs/pull/N/head no longer show as not found#25947
Problem
Some open pull requests lack refs/pull/<number>/head even though GitHub returns their data. The detail and action-state queries compare the base branch against that ref, so GitHub answers with the full pull request plus one NOT_FOUND on repository.pullRequest.baseRef.compare. The GraphQL client read any all-NOT_FOUND answer as a missing resource. The panel showed "Pull request #N not found", merge and update-branch failed the same way, and the watch gave up after eight failed reads. The log said only "GitHub could not find the requested resource".
Change
- The detail and action-state reads accept exactly that answer (HTTP 200, no other error) and keep the data GitHub sent with it. The comparison is unknown, rather than spending a second request to compare by head SHA. Merge and update-branch proceed again. The UI still does not offer Update branch while the comparison is unknown, as when GitHub cannot compare. The requested-reviewer retry from #19564 also runs when the missing ref comes with a refused reviewer.
isNotFoundOnlycounts aNOT_FOUNDas a missing resource only without a path, on a root field (with its list items), or onrepository.pullRequest. A deeper one, like this comparison, is a response error.- GraphQL errors keep GitHub's message and path in
githubErrors, now onGitHubApiNotFoundErrortoo, so a failure like this one names its cause in the log.
The last two changes belong to the same defect: they are why a failed comparison was reported, and logged, as a missing pull request.
This is a small fix for an obvious bug, sent without an issue: an existing pull request is reported missing, and the change stays inside GitHub GraphQL error handling.
Reproduction
The affected repository is private, so names and numbers are replaced. N is the affected pull request, M an open neighbour that has both refs.
| 1 | gh api repos/<owner>/<repo>/git/ref/pull/N/head # 404, while refs/pull/N/merge exists |
| 2 | |
| 3 | query { repository(owner: "<owner>", name: "<repo>") { pullRequest(number: N) { |
| 4 | headRefOid baseRef { compare(headRef: "refs/pull/N/head") { behindBy } } } } } |
| 5 | |
| 6 | data.repository.pullRequest is present, compare is null, and errors is: |
| 7 | [{"type":"NOT_FOUND","path":["repository","pullRequest","baseRef","compare"], |
| 8 | "message":"Could not resolve head ref 'refs/pull/N/head'."}] |
Verification
Linux, Node 24, from packages/source-control-github. Using the gh credential, GitHubPullRequestProvider.getChangeRequest returned:
| 1 | main {"number":N,"ok":false,"reason":"not-found","detail":"GitHub could not find the requested resource, or the credential cannot see it."} |
| 2 | {"number":M,"ok":true,"state":"open","baseComparison":"up-to-date","behindBy":0} |
| 3 | branch {"number":N,"ok":true,"state":"open","baseComparison":"unknown","behindBy":null} |
| 4 | {"number":M,"ok":true,"state":"open","baseComparison":"up-to-date","behindBy":0} |
vp test run src/server/GitHubPullRequestApi.test.ts src/server/gitHubGraphQlClient.test.ts passes 124 tests. Reverting the three production files to main makes 10 of them fail. vp run check:changed passes.
Not verified: the panel and the watch in a running app, merge and update-branch against the real pull request (tests only), and GitHub Enterprise.
Models: Claude Opus 5.5 (implementation), GPT-6.1-Sol (independent review). Harness: Claude Code through T3 Code.
🤖 Generated with Claude Code
Added 1 commit
- fix(github): pull requests missing refs/pull/N/head no longer show as not foundafba1ef
Approvability
Verdict: Approved at afba1ef
Macroscope's review found this PR approvable — This is a focused GitHub GraphQL error-handling fix that preserves existing pull-request data when only the synthetic head ref is missing, while retaining diagnostics for genuine failures. The production changes are narrowly scoped and covered by targeted regression tests.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review.
External image Recent review info
-
External image Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: main
- File: .coderabbit.config.ts
- Commit: 30084f0
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Advanced
- Run ID:
5edd8dfb-9246-4c92-8bb4-3d6c9e33682f
External image Commits
Reviewing files that changed from the base of the PR and between 59737e855d79d5d33ed12428ccdd0efb6a71646c and 8d04b0c7f56dc46652faa49db5e42b5e8c3a1054.
External image Files selected for processing: 3
packages/source-control-github/src/server/GitHubPullRequestApi.test.tspackages/source-control-github/src/server/GitHubPullRequestApi.tspackages/source-control-github/src/server/gitHubGraphQlClient.ts
External image Files with no reviewable changes: 1
- packages/source-control-github/src/server/gitHubGraphQlClient.ts
Limit details: You’ve used all 10 included reviews currently available.
Walkthrough
The GitHub GraphQL client now classifies
NOT_FOUNDerrors by response path and includes paths in error descriptions. Pull-request detail and action-state reads decode available data when the base-ref comparison is missing.Changes: Pull-request missing-ref handling
Layer / File(s) Summary Path-aware GraphQL error reporting
packages/source-control-github/src/server/gitHubGraphQlClient.ts,packages/source-control-github/src/server/GitHubRequestPolicy.ts,packages/source-control-github/src/server/GitHubPullRequestApi.ts,packages/source-control-github/src/server/gitHubGraphQlClient.test.ts,packages/source-control-github/src/server/GitHubPullRequestApi.test.tsThe GraphQL client classifies NOT_FOUNDerrors by path and includes paths in formatted error descriptions.GitHubApiNotFoundErroraccepts GitHub error messages. Tests cover path-based classification and error formatting.Missing-ref read recovery
packages/source-control-github/src/server/GitHubPullRequestApi.ts,packages/source-control-github/src/server/GitHubPullRequestApi.test.tsPull-request detail and action-state reads decode response data when the base-ref comparison is missing. The reviewer-refusal fallback accepts that error. Tests cover detail reads, retries, merge and update-branch actions, and errors that remain failures. Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Bug fix
Suggested reviewers:
juliusmarminge,maria-rcks,t3dotgg
Merge Risk: External image Minimal · up to 8d04b
Pull requests with a missing comparison can remain visible while update-branch stays unavailable. No merge-blocking risk was established.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly and concisely describes the main fix: GitHub pull requests with missing head refs no longer appear as not found. Description check Passed The description covers the problem, reproduction, implementation, scope rationale, verification results, and unverified scenarios. It omits the exact “Scope and approval” heading, but it explains why … Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request. Full details: Description check
Explanation
The description covers the problem, reproduction, implementation, scope rationale, verification results, and unverified scenarios. It omits the exact “Scope and approval” heading, but it explains why the focused bug fix does not require a prior issue or approval.
Finishing Touches
Generate unit tests (beta)
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Usage-based review receipt
- Mode: Continue automatically
- Reviewed files: 2
- Charged: $0.50
- View usage details
Note
This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.
Note
Written by gpt-6.1-sol on behalf of Maria
Verified in a real dev environment
partial verification at exact head afba1efc88adbc62b7fdd4de76617b5e8d5a8973, linux, chrome, real github credentials, and real codex gpt-6.1-sol through the local proxy. no mocks, fixtures, or demo data. no code changes or pushes.
- installed and ran
github/main(32ecd71726) in/home/user/main, then stopped its captured process group before running the pr with isolated/home/user/t3code/.t3state. only one dev server ran at a time. - added projects for real git repositories through the app. submitted real codex turns on main and the pr. both returned the requested github link. on the pr, clicking the provider response opened #25947 inside the app; summary and the five-file code view loaded.
- opened nonexistent #99999999 through the same client. both versions showed the expected not-found panel. on the pr, the actual websocket response preserved github's message and field path, confirming the changed diagnostic through the github provider, server, and client.
short runtime transcript captured from the actual client websocket:
| 1 | Request tag=pullRequests.detail |
| 2 | host=github.com repository=pingdotgg/t3code number=99999999 |
| 3 | Exit Failure PullRequestOperationError operation=detail reason=not-found |
| 4 | GitHub could not find the requested resource, or the credential cannot see it. |
| 5 | GitHub said: Could not resolve to a PullRequest with the number of 99999999. |
| 6 | (at repository.pullRequest) |
blacksmith passed 124 focused tests in GitHubPullRequestApi.test.ts and gitHubGraphQlClient.test.ts. vp run check:changed HEAD^ passed format, lint, graphql generation, knip, typechecks for 11 packages, and both test files. the worker needed the contributor head fetched with depth 2 because its initial snapshot lacked parent history. hosted pr status reported 10 successful checks, none pending or failing.
this clip shows the normal path, not missing-ref recovery. uploaded playback and seeking were checked.
real codex response opens the github pr summary and code view
pr head loads github pr details beside the real codex response
matching neighboring case on main and the pr: a genuinely nonexistent pr stays not found.
main shows the genuine missing-pr error
pr head preserves the genuine missing-pr error
Not verified
the central missing-head-ref recovery remains unverified against live github. the report anonymizes its affected private repository and pr. #25947 itself has a working refs/pull/25947/head comparison. a read-only search of 600 accessible t3code prs found no NOT_FOUND at repository.pullRequest.baseRef.compare; every pr with a base ref had a working comparison. the original bug could not be reproduced on main and its recovery could not be exercised on the pr without inventing a response, which this verification forbids.
also unverified: watch recovery for that missing-ref case, the combined refused-reviewer retry, merge/update-branch mutations, github enterprise, native desktop/mobile, windows/macOS, and remote/relay/tunnel connections. no merge or update-branch mutation was attempted. no labels, branches, or other prs were changed.
this is not a full verification sign-off. completing it requires access to an affected real pr. the only published change is this verification comment.
Added 1 commit
- chore: merge main into missing pull ref fix59737e8
Note
Written by gpt-6.1-sol on behalf of Maria
merged current github/main (30084f0018c5) into the existing contributor head without rebasing. resolved the graphql client conflict by preserving this pr's messages and field paths alongside main's error-type metadata. the diff against main remains five files, 233 additions and 27 deletions.
blacksmith vp run check:changed 30084f0018c5751a07291222e8d04e16d513700a passed format, lint, knip, graphql generation, 11 package typechecks, and 129 tests. two independent read-only reviews approved 8d04b0c7f56dc46652faa49db5e42b5e8c3a1054 without findings. pushed to the original contributor branch without force.
live recovery against a genuinely missing github pull ref remains unverified, as recorded in the existing verification comment. no new ui behavior was introduced by this merge resolution.
Added 1 commit
- chore: merge main into missing pull ref fix8d04b0c