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
Server: thread launch / worktree provisioning (create_threads, t3_thread_launch)
What happened
An agent launched a new worktree thread through the T3 MCP and chose the branch name werkstatt/baseline. The repo already had a local branch named werkstatt. The thread failed at once:
Workspace preparation failed during provision worktree: Git command failed in GitVcsDriver.createWorktree.createBranch (<repo>): git worktree add failed
Git stores refs as paths. When refs/heads/werkstatt exists, no refs/heads/werkstatt/* ref can be made. The reverse also fails: when werkstatt/x exists, you cannot create werkstatt. git check-ref-format --branch accepts both names, so the conflict only shows up when the ref is written.
This is the same bug as #16163, but for names the caller picks. #16167 fixed only the built-in temporary prefix. ThreadLaunchService checks refs/heads/${WORKTREE_BRANCH_PREFIX} and flattens the name, but only when isTemporaryWorktreeBranch(branch) is true. An explicit branch name from an agent, the MCP tools, or the UI goes to createWorktree unchecked.
There is a second, smaller problem. createWorktree runs createBranchAt(..., "git worktree add failed") through executeGitWithStableDiagnostics. The fallback detail replaces git's stderr, and no failure class matches a ref-namespace conflict. So the UI says git worktree add failed for a git branch call and drops git's one-line cause ('refs/heads/werkstatt' exists; cannot create 'refs/heads/werkstatt/baseline'). The agent that made the call cannot see why it failed or how to fix it.
Steps to reproduce
Plain git (git 2.47.3):
d=$(mktemp -d) && cd "$d"
git init -q -b main && git commit -q --allow-empty -m init
git branch werkstatt
git check-ref-format --branch werkstatt/baseline # accepted, exit 0
git branch --no-track -- werkstatt/baseline main # what createWorktree runs first
# fatal: cannot lock ref 'refs/heads/werkstatt/baseline': 'refs/heads/werkstatt' exists; cannot create 'refs/heads/werkstatt/baseline'
git branch foo/bar && git branch foo # reverse case
# fatal: cannot lock ref 'refs/heads/foo': 'refs/heads/foo/bar' exists; cannot create 'refs/heads/foo'
git worktree add -q -b werkstatt-baseline ../wt main # flat sibling worksIn T3 Code:
- In a repo registered as a project, run
git branch werkstatt. - Have an agent call
t3_thread_launch(orcreate_threads) with a worktree strategy, basemain, and branchwerkstatt/baseline. Starting a worktree thread from the UI with that branch name also works. - The thread fails during provision-worktree with the message above.
Expected behavior
- T3 checks an explicit branch name for ref-namespace conflicts in both directions before it creates the thread or touches the repo.
- On a conflict, the tool call returns a clear error to the caller, for example:
branch "werkstatt" exists, so "werkstatt/baseline" cannot be created; use e.g. "werkstatt-baseline". The agent can then retry in the same turn, and no failed thread is left behind. Explicit names should not be renamed silently. Only temporary names should flatten, as fix(server): worktree threads survive a local branch named t3code #16167 already does. - If git still fails, the error shows git's stderr and names the step that failed (
git branch, notgit worktree add).
Actual behavior
The thread is created and then fails in provision-worktree with only git worktree add failed. The cause is hidden, so the agent cannot correct the name, and the user has to look at the repo's refs to find out why.
Impact
Agents often pick topic/name branch names. Any repo that has a branch with the same name as the topic (werkstatt, exp, feature, ...) makes every such launch fail with no clue why. Retrying with the same name always fails.
Suggested test case
In the ThreadLaunchService tests, next to the #16167 test for a blocking t3code branch:
- A repo with branch
werkstatt, and a launch with explicit branchwerkstatt/baseline. The launch is rejected before a thread is created, the error namesrefs/heads/werkstatt, and no branch or worktree is left behind. - A repo with branch
werkstatt/x, and a launch with explicit branchwerkstatt. Same result as case 1. - A repo with branch
werkstatt, and a launch with explicit branchwerkstatt-baseline. The launch succeeds, which rules out a check that is too broad. - A
GitVcsDriverCoretest: whencreateWorktreehits a ref-namespace conflict, theGitCommandErrordetail or reason carries git's cause, not the staticgit worktree add failed.
Version or commit
Desktop 0.1.6 (Linux). The code paths above were checked on main at 47f2c8d (2026-11-02): ThreadLaunchService.ts around the isTemporaryWorktreeBranch check, and GitVcsDriverCore.ts createWorktree / createBranchAt.
Environment
Linux x64, git 2.47.3.
Activity