fix(github): keep gh's default repository when local remotes exist#24551
Problem
A fork checkout with origin marked by gh repo set-default, an upstream remote, and a local-path remote sends PR creation to upstream. A branch pushed only to the fork then fails with GitHub's Validation Failed; head invalid response.
Change
Ignore hostless remotes when selecting GitHub's base repository so the marked fork remains selected. Reuse the existing parsers together to preserve userless SCP remotes, SSH aliases, and the existing handling of other hosts. Add regression coverage for the reported failure and parser compatibility.
Scope and approval
Fixes https://github.com/pingdotgg/t3code/issues/24383 GitCafe: https://git.cafe/pingdotgg/t3code/issues/24383
Triaged bug via the automated issue flow. This is a focused correction to existing repository selection; no client or contract changes.
Verification
- Red regression: expected the marked fork
me/web, received upstreamacme/web(1 failed, 3 passed). - Final repository-resolution test file: 4 passed. GitHub provider server tests: 270 passed. Package typecheck: exit 0. Targeted lint and
git diff --check: passed. - Two independent reviewers approved the revised diff after the SCP compatibility regression was corrected.
| Runtime case | Observed request | Result |
|---|---|---|
| Before, local remote present | POST upstream /repos/pingdotgg/t3code/pulls | 422, head invalid |
| Before control, remove only local remote | POST fork /repos/juliusmarminge/t3code/pulls | 201 |
| After, local remote still present | POST fork /repos/juliusmarminge/t3code/pulls | 201 |
Sanitized runtime transcript, structured trace, reproduction command and fixture.
The real Linux dev server was driven through the web client's source-control command. Runtime proof uses implementation commit e9322b8756; the subsequent main integration changes only Macroscope ignore configuration, and the focused tests pass again at the PR head. There are no changed render paths (capture matrix 0/0). Desktop/mobile shells and remote connection modes were not separately exercised. Temporary reproduction PR branches were deleted after testing.
Models: Claude Opus 5.5 and GPT-6.1-Sol, through T3 Code (Claude Agent and Codex harnesses).
Checks
Added 4 commits
- fix(github): a local-path remote no longer hides the remote gh marked as base (#24383)1d05d43
- Merge remote-tracking branch 'origin/main' into fix/issue-24383a90e45f
- test(github): reproduce marked fork lost when a local remote is present (#24383)b21d87b
- fix(github): a userless SCP remote still counts when skipping hostless remotes (#24383)e9322b8
Approvability
Verdict: Approved at a90e45f
Macroscope's review found this PR approvable — This is a narrowly scoped GitHub repository-resolution bug fix that ignores hostless local remotes while preserving GitHub CLI’s marked default repository. Normal remotes and SSH compatibility remain covered by regression tests, with no schema, configuration, or static-analysis changes.
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: fix/issue-24383
- File: .coderabbit.config.ts
- Commit: a90e45f
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
e22e2c5c-6d49-4f68-9a0b-b6a9e4ed2c60
External image Commits
Reviewing files that changed from the base of the PR and between eea989536849e5b5049987ee24318b5a77326542 and a90e45f2bd71c882bf9b48d935e6cff6fb45576d.
External image Files selected for processing: 2
packages/source-control-github/src/server/gitHubRepositoryResolution.test.tspackages/source-control-github/src/server/gitHubRepositoryResolution.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.
Walkthrough
The base repository selection now skips remotes only when both repository and host parsing return
null. Tests cover scheme-less GitHub remotes, non-GitHub and malformed remotes, and local-path remotes.Changes: GitHub base selection
Layer / File(s) Summary Remote parsing and base selection
packages/source-control-github/src/server/gitHubRepositoryResolution.ts,packages/source-control-github/src/server/gitHubRepositoryResolution.test.tsselectGitHubBaseRepositoryskips a remote only when bothparseGitRemoteRepositoryandparseGitRemoteHostreturnnull. Tests cover scheme-less GitHub remotes, fallback cases, and resolving a GitHub locator when a local-path remote is present.Priority: External image Normal
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers:
maria-rcks,maxwellyoung
Merge Risk: External image Minimal · up to a90e4
The change addresses selection of the marked GitHub repository when local-path remotes are present. No outstanding issue prevents merge after normal checks.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title names the fix (keeping gh's default repository selected when local remotes exist) and matches the changeset, which ignores hostless remotes in selectGitHubBaseRepository. It is a conventiona… Description check Passed The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. It explains the failure with a reproduction path, describes the parser reuse and compatibil… Linked Issues check Passed Issue #24383requires GitHub PR repository selection to ignore non-GitHub remotes and retain the repository marked bygh repo set-default. The change skips a remote only when both repository parsing…Out of Scope Changes check Passed The changes stay within issue #24383. The source change updates GitHub repository selection and its documentation. The added tests cover the reported local-remote regression and parser compatibility. …Full details: Title check
Explanation
The title names the fix (keeping gh's default repository selected when local remotes exist) and matches the changeset, which ignores hostless remotes in selectGitHubBaseRepository. It is a conventional commit title in plain language and fits the author's stated problem.
Full details: Description check
Explanation
The description follows the template's main sections: Problem, Change, Scope and approval, and Verification. It explains the failure with a reproduction path, describes the parser reuse and compatibility handling, links issue
#24383as a triaged bug, and gives concrete test results and runtime evidence. The Verification section names the models used, as the template requests. Minor gaps: the template asks for focused tests or manual checks, and the author provides them, so no gap is material. The scope section cites an automated issue flow rather than a maintainer approval comment, which a reviewer may want to confirm.
Full details: Linked Issues check
Explanation
Issue
#24383requires GitHub PR repository selection to ignore non-GitHub remotes and retain the repository marked bygh repo set-default. The change skips a remote only when both repository parsing and host parsing return no result. This skips local-path remotes while preserving userless SCP remotes. The tests cover a local remote with a markedorigin, scheme-less GitHub remotes, GitLab mirrors, malformed URLs, SSH aliases, and other selection cases. The focused tests also verify the resolved repository locator.
Full details: Out of Scope Changes check
Explanation
The changes stay within issue
#24383. The source change updates GitHub repository selection and its documentation. The added tests cover the reported local-remote regression and parser compatibility. No unrelated client, contract, or render changes are shown.
Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | 20.9 KiB | 20.9 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Codex | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
| Claude | Total thread wire | 5.0 KiB | 5.0 KiB | 0 B (0.0%) | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | 0 B (0.0%) | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | 21.2 KiB | 21.2 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Claude | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
Baseline: eea9895 · PR result: a90e45f · Source CI: success
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.