Before submitting
Area
apps/web, apps/server
Steps to reproduce
- Add a project that is a valid Git repository but has no commits (
HEAD is unborn).
- Configure new threads to use worktree mode.
- Open a new draft, enter a prompt, and send it.
thread.created succeeds, then git worktree add fails because there is no commit from which to create the worktree.
- Bootstrap cleanup emits
thread.deleted for the provisional thread.
- Retry sending the prompt, restart T3 Code, or reopen the project's new-thread draft.
The no-commit worktree failure is already tracked in #2148. This issue tracks the separate persistent state left behind after that or another bootstrap failure.
Expected behavior
When bootstrap cleanup deletes a provisional thread, the client should invalidate or regenerate the draft's thread ID. Retrying should use a fresh aggregate ID, preserve the prompt, and either retry bootstrap or return the original actionable error.
Actual behavior
The composer draft remains persisted in t3code:composer-drafts:v1 and continues to map the project draft to the deleted thread ID. Every retry attempts thread.create with that tombstoned aggregate ID and fails with:
Orchestration command invariant failed (thread.create):
Thread '<thread-id>' already exists and cannot be created twice.
Restarting T3 Code does not fix the problem because the mapping survives in local storage. Changing defaultThreadEnvMode to local also does not repair an existing draft because its stored threadId remains unchanged.
The event and trace sequence in this reproduction was:
thread.created
GitCommandError: git worktree add failed
thread.deleted (29 ms after creation)
thread.create retries with the same thread ID
OrchestrationCommandInvariantError: already exists and cannot be created twice
The relevant persisted draft state remained equivalent to:
{
"threadId": "<deleted-thread-id>",
"envMode": "worktree",
"worktreePath": null,
"promotedTo": null
}
The server correctly retains the original thread.created and thread.deleted events, so the deleted aggregate ID cannot be reused. The client draft must therefore stop reusing it after cleanup.
Impact
Blocks work completely
The affected project appears permanently locked to the deleted ID. New-thread retries and application restarts continue to produce the invariant error.
Version or commit
T3 Code Nightly 0.0.29-nightly.20260725.899
Environment
Linux, Electron 41.5.0, repository with an unborn master branch and uncommitted files.
Logs or stack traces
OrchestrationCommandInvariantError: Orchestration command invariant failed (thread.create): Thread '<thread-id>' already exists and cannot be created twice.
at requireThreadAbsent
at decideOrchestrationCommand
at orchestration.command.thread.create
Workaround
Manually repair the persisted composer draft by preserving its prompt and draft ID, assigning a fresh thread UUID, switching it to local mode, and reloading T3 Code.
Related issues: #2148, #378, #624.
Before submitting
Area
apps/web, apps/server
Steps to reproduce
HEADis unborn).thread.createdsucceeds, thengit worktree addfails because there is no commit from which to create the worktree.thread.deletedfor the provisional thread.The no-commit worktree failure is already tracked in #2148. This issue tracks the separate persistent state left behind after that or another bootstrap failure.
Expected behavior
When bootstrap cleanup deletes a provisional thread, the client should invalidate or regenerate the draft's thread ID. Retrying should use a fresh aggregate ID, preserve the prompt, and either retry bootstrap or return the original actionable error.
Actual behavior
The composer draft remains persisted in
t3code:composer-drafts:v1and continues to map the project draft to the deleted thread ID. Every retry attemptsthread.createwith that tombstoned aggregate ID and fails with:Restarting T3 Code does not fix the problem because the mapping survives in local storage. Changing
defaultThreadEnvModetolocalalso does not repair an existing draft because its storedthreadIdremains unchanged.The event and trace sequence in this reproduction was:
The relevant persisted draft state remained equivalent to:
{ "threadId": "<deleted-thread-id>", "envMode": "worktree", "worktreePath": null, "promotedTo": null }The server correctly retains the original
thread.createdandthread.deletedevents, so the deleted aggregate ID cannot be reused. The client draft must therefore stop reusing it after cleanup.Impact
Blocks work completely
The affected project appears permanently locked to the deleted ID. New-thread retries and application restarts continue to produce the invariant error.
Version or commit
T3 Code Nightly
0.0.29-nightly.20260725.899Environment
Linux, Electron
41.5.0, repository with an unbornmasterbranch and uncommitted files.Logs or stack traces
Workaround
Manually repair the persisted composer draft by preserving its prompt and draft ID, assigning a fresh thread UUID, switching it to local mode, and reloading T3 Code.
Related issues: #2148, #378, #624.