[Bug]: Worktree checkout of GitLab merge requests always fails — fetchPullRequestBranch hardcodes GitHub's refs/pull/<n>/head
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
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
- Open a project whose
originis a GitLab remote (mine is self-hosted, SSH:git@gitlab.<company>.de:group/repo.git). Provider detection works (MRs list and resolve fine in the dialog, thanks to #6061). - Open Checkout merge request, enter any MR number (open or closed, source branch exists on the remote).
- Click Worktree.
Expected behavior
The MR head branch is fetched, a worktree is created, and the draft thread opens on it — same as Local mode, which works fine for the same MR.
Actual behavior
The dialog shows "Failed to prepare merge request thread." for every GitLab MR.
Root cause (from reading apps/server/src/vcs/GitVcsDriverCore.ts in the shipped bundle):
-
preparePullRequestThread(worktree mode) materializes the MR head viamaterializePullRequestHeadBranch. -
For my GitLab MR the resolved head-repository name-with-owner is empty, so the primary path is skipped and both the primary and fallback attempts run
gitCore.fetchPullRequestBranch, which hardcodes GitHub's ref layout:git fetch --quiet --no-tags origin +refs/pull/<n>/head:refs/heads/<branch> -
GitLab does not expose
refs/pull/*; its equivalent isrefs/merge-requests/<n>/head. So the fetch exits 128 (fatal: couldn't find remote ref refs/pull/533/head), both attempts fail identically, and the whole prepare fails.
Verified manually in the same repo:
git fetch origin refs/pull/533/head→fatal: couldn't find remote ref(exit 128)git fetch origin refs/merge-requests/533/head→ worksgit fetch origin <headBranch>:<headBranch>→ works
fetchPullRequestHeadCommit has the same hardcoded refs/pull/<n>/head and will fail the same way when refreshing a reused worktree.
Local mode is unaffected because it goes through the source-control provider's own checkoutChangeRequest instead of the generic git driver.
Suggested fix: route the MR ref through the source-control provider (which already knows the host is GitLab) or map provider → ref namespace (refs/pull vs refs/merge-requests) in fetchPullRequestBranch / fetchPullRequestHeadCommit. Falling back to fetching headBranch by name when the head repo is the origin repo would also cover it.
Impact
Major degradation or frequent failure
Version or commit
0.0.34-nightly.20260813.1082 (desktop, macOS). Bug still present in main: apps/server/src/vcs/GitVcsDriverCore.ts lines ~2799 and ~2827.
Environment
macOS 26.5.2, T3 Code Nightly desktop, self-hosted GitLab (SSH remote)
Logs or stack traces
GitPullRequestMaterializationError: Failed to materialize pull request #533 branch claude/sdw-roboflow-prototype-c87757 as claude/sdw-roboflow-prototype-c87757.
at preparePullRequestThread (apps/server/dist/bin.mjs:45576:109)
at ws.rpc.git.preparePullRequestThread (apps/server/dist/bin.mjs:36905:111) {
[cause]: AggregateError: Repository-head and pull-request-ref fetches both failed for pull request #533.
[cause]: GitCommandError: Git command failed in GitVcsDriver.fetchPullRequestBranch (<repo path>): git fetch pull request branch failed
}
}
Workaround
Use Local mode, or pre-create the worktree manually (git worktree add ../wt <headBranch> after fetching the branch) — preparePullRequestThread then detects the existing checkout and reuses it without fetching.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/server/src/vcs/GitVcsDriverCore.ts, focusing on fetchPullRequestBranch, fetchPullRequestHeadCommit, and their callers preparePullRequestThread and materializePullRequestHeadBranch. Reproduce the failure with a GitLab merge request and compare the refs/pull//head and refs/merge-requests//head fetches. Done means Worktree mode fetches and opens a GitLab MR while existing GitHub behavior remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, gitlab, typescript
- Domain
- backend, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100