You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
prepareWorktree only checks that the originremote exists before resolving the base ref against it. It never checks that the base branch has a remote-tracking counterpart. Any base branch that exists locally but was never pushed therefore fails the whole bootstrap.
This is the same failure class as #5408, but #5556 only fixed the "repository has no origin at all" case. A repo with a perfectly healthy origin still fails here.
Set the project's new-thread mode to New worktree and leave Start from origin enabled.
Start a thread based on main. It works. T3 Code creates worktree branch t3code/<hash> locally; that branch is never pushed.
Open a new-thread draft and, in the base-ref picker, select that local-only branch as the base (the toolbar renders it as From origin/t3code/… — see below).
Enter a prompt and send.
Reproduced deterministically on the affected repo — every send with that base branch fails, and switching the base back to main succeeds immediately.
Minimal shell repro of the failing step:
git -C <repo> remote -v # origin exists
git -C <repo> branch feature/local-only # never pushed
git -C <repo> rev-parse --verify "refs/remotes/origin/feature/local-only^{commit}"# fatal: Needed a single revision (exit 128)
Expected behavior
When the base branch has no remote-tracking ref, prepareWorktree should fall back to the local ref instead of aborting — the same way #5556 falls back when there is no origin at all. Alternatively, "Start from origin" should be disabled (or the label should not read origin/<branch>) for a base branch with no remote counterpart.
Creating a worktree thread on top of an unpushed branch is a completely ordinary thing to do — it is exactly what happens when you start a follow-up thread on the branch of an earlier T3 Code thread, since T3-generated t3code/* branches are local until you push them.
Actual behavior
Bootstrap aborts at resolveRemoteTrackingCommit and the provisional thread is rolled back ~330 ms after it was created:
thread.created (server:bootstrap-thread-create:…)
GitCommandError: Git command failed in GitVcsDriver.resolveRemoteTrackingCommit
thread.deleted (server:bootstrap-thread-delete:…)
The failing command is built here — the base ref is passed straight through with an origin/ prefix and rev-parse --verify is expected to succeed:
The UI does not gate the option either — resolveBranchTriggerLabel renders From origin/<branch> based only on resolvedActiveBranchIsRemote === false, with no check that refs/remotes/origin/<branch> actually exists (apps/web/src/components/BranchToolbar.logic.ts:183-189). So the picker advertises a base ref that cannot be resolved.
Compounding symptom. Because the rollback soft-deletes the provisional thread while the client keeps the same pre-allocated threadId, the retry surfaces an unrelated-looking error instead of the actionable git one:
OrchestrationCommandInvariantError: Orchestration command invariant failed (thread.create):
Thread '20877f92-…' already exists and cannot be created twice.
That is the #4647 / #5721 stale-draft-ID behavior, still observed on 0.0.33 — noting it only because it is what the user actually sees. The git stderr is never surfaced in the UI, so the visible error points nowhere near the real cause. Four consecutive drafts were burned this way in my state.sqlite, each created and deleted within ~330 ms:
thread
created_at
deleted_at
20877f92-…
10:08:34.077
10:08:34.406
9cae6597-…
09:59:25.674
09:59:25.996
4fd16c01-…
09:56:57.886
09:56:58.271
c57fccdb-…
09:56:36.309
09:56:36.665
All four had "branch": "t3code/design-watch-evolution-page" in their thread.created payload — a local-only branch created by an earlier T3 Code thread. The last thread that succeeded had "branch": "main".
Impact
Blocks work completely
Version or commit
T3 Code 0.0.33 (AUR t3code-bin 0.0.33-2). The prepareWorktree code path above is unchanged on main @ 5d76653, so this should still reproduce on nightly.
# ~/.t3/userdata/logs/server.trace.ndjson — root cause
GitCommandError: Git command failed in GitVcsDriver.resolveRemoteTrackingCommit (<repo>): Git command exited with a non-zero status.
at resolveRemoteTrackingCommit (…/apps/server/dist/bin.mjs:44202:145)
at resolveRemoteTrackingCommit (definition) (…/apps/server/dist/bin.mjs:34228:45)
at ws.rpc.orchestration.dispatchCommand (…/apps/server/dist/bin.mjs:35718:111)
OrchestrationDispatchCommandError: Git command failed in GitVcsDriver.resolveRemoteTrackingCommit (<repo>): Git command exited with a non-zero status.
at toBootstrapDispatchCommandCauseError (…/apps/server/dist/bin.mjs:48302:63)
# then, on retry of the same draft — what the user actually sees
OrchestrationCommandInvariantError: Orchestration command invariant failed (thread.create): Thread '20877f92-…' already exists and cannot be created twice.
at invariantError (…/apps/server/dist/bin.mjs:22122:9)
at requireThreadAbsent (…/apps/server/dist/bin.mjs:22164:21)
at orchestration.command.thread.create (…/apps/server/dist/bin.mjs:23743:18)
Workaround
Any one of:
Turn off Start from origin for the project (newWorktreesStartFromOrigin: false) — the worktree then branches off the local ref and thread creation succeeds.
Push the base branch once (git push -u origin <branch>) so the remote-tracking ref exists.
Pick a base branch that does exist on origin (e.g. main).
An already-wedged draft still needs the localStorage cleanup from #4647.
Before submitting
Area
apps/server
Steps to reproduce
prepareWorktreeonly checks that theoriginremote exists before resolving the base ref against it. It never checks that the base branch has a remote-tracking counterpart. Any base branch that exists locally but was never pushed therefore fails the whole bootstrap.This is the same failure class as #5408, but #5556 only fixed the "repository has no
originat all" case. A repo with a perfectly healthyoriginstill fails here.originremote (so the fix(server): skip origin fetch when creating worktrees in repos without an origin remote #5556 guard passes and the fetch succeeds).main. It works. T3 Code creates worktree brancht3code/<hash>locally; that branch is never pushed.Reproduced deterministically on the affected repo — every send with that base branch fails, and switching the base back to
mainsucceeds immediately.Minimal shell repro of the failing step:
Expected behavior
When the base branch has no remote-tracking ref,
prepareWorktreeshould fall back to the local ref instead of aborting — the same way #5556 falls back when there is nooriginat all. Alternatively, "Start from origin" should be disabled (or the label should not readorigin/<branch>) for a base branch with no remote counterpart.Creating a worktree thread on top of an unpushed branch is a completely ordinary thing to do — it is exactly what happens when you start a follow-up thread on the branch of an earlier T3 Code thread, since T3-generated
t3code/*branches are local until you push them.Actual behavior
Bootstrap aborts at
resolveRemoteTrackingCommitand the provisional thread is rolled back ~330 ms after it was created:The failing command is built here — the base ref is passed straight through with an
origin/prefix andrev-parse --verifyis expected to succeed:apps/server/src/vcs/GitVcsDriverCore.ts:2958-2974(main @ 5d76653)and the caller, where the only guard is
remoteExists—apps/server/src/ws.ts:1011-1028(main @ 5d76653):The UI does not gate the option either —
resolveBranchTriggerLabelrendersFrom origin/<branch>based only onresolvedActiveBranchIsRemote === false, with no check thatrefs/remotes/origin/<branch>actually exists (apps/web/src/components/BranchToolbar.logic.ts:183-189). So the picker advertises a base ref that cannot be resolved.Compounding symptom. Because the rollback soft-deletes the provisional thread while the client keeps the same pre-allocated
threadId, the retry surfaces an unrelated-looking error instead of the actionable git one:That is the #4647 / #5721 stale-draft-ID behavior, still observed on 0.0.33 — noting it only because it is what the user actually sees. The git stderr is never surfaced in the UI, so the visible error points nowhere near the real cause. Four consecutive drafts were burned this way in my
state.sqlite, each created and deleted within ~330 ms:20877f92-…9cae6597-…4fd16c01-…c57fccdb-…All four had
"branch": "t3code/design-watch-evolution-page"in theirthread.createdpayload — a local-only branch created by an earlier T3 Code thread. The last thread that succeeded had"branch": "main".Impact
Blocks work completely
Version or commit
T3 Code 0.0.33 (AUR
t3code-bin 0.0.33-2). TheprepareWorktreecode path above is unchanged onmain@5d76653, so this should still reproduce on nightly.Environment
Arch Linux (kernel 7.1.8), Wayland/Hyprland, provider
claudeAgent(claude-opus-5). Settings:defaultThreadEnvMode: "worktree",newWorktreesStartFromOrigin: true.Logs or stack traces
Workaround
Any one of:
newWorktreesStartFromOrigin: false) — the worktree then branches off the local ref and thread creation succeeds.git push -u origin <branch>) so the remote-tracking ref exists.origin(e.g.main).An already-wedged draft still needs the localStorage cleanup from #4647.