Skip to content

[Bug]: "Start from origin" is offered for repositories with no remote, failing every thread send #5408

Description

@nhorto

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web

Steps to reproduce

  1. Create or open a local Git repository that has at least one commit and no remotes (git remote -v prints nothing).
  2. Set the project's new-thread mode to New worktree.
  3. Leave the base-ref control on From origin/main — i.e. "Start from origin" enabled.
  4. Enter a prompt and send.

Expected behavior

"Start from origin" should not be offered (or should be disabled) when the repository has no remote, or the server should fall back to the local base branch. Creating the thread should succeed.

Actual behavior

The bootstrap fails and the provisional thread is rolled back:

Git command failed in GitVcsDriver.fetchRemote (<repo path>): git fetch origin failed

startFromOrigin: true makes the server run gitWorkflow.fetchRemote({ remoteName: "origin" }) inside prepareWorktree (apps/server/src/ws.ts, dispatchBootstrapTurnStart) before creating the worktree. With no remote configured, git fails and the whole thread.turn.start bootstrap aborts. Nothing in the UI or the command path checks whether a remote exists before offering, enabling, or acting on the option, so the user is presented with a choice that cannot possibly be satisfied for this repository.

The option was enabled on every fresh draft for the affected project in my testing. The schema default is false:

// apps/web/src/composerDraftStore.ts
startFromOrigin: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false)))

but the value is sticky — createDraftThreadState carries it forward from the previous draft — so once it is on for a project it propagates to every new draft. I can't say whether it was originally set deliberately; either way it shouldn't persist into a repository that has no remote.

Isolating contrast across three projects on the same machine, same client, same model settings:

Project Remote Result
A origin → github.com/… thread starts normally
B origin → github.com/… thread starts normally
C none every send fails

Project C is otherwise healthy — 5 commits, valid main, clean HEAD. Turning "Start from origin" off makes it work immediately (verified: thread created, worktree built, agent started).

Compounding interaction with #4647

This is more than a confusing error, because the failed bootstrap also burns the draft's thread ID. The rollback issues a soft thread.delete, requireThreadAbsent matches on ID alone, and the web client keeps the same pre-generated threadId in t3code:composer-drafts:v1. Every retry then fails with:

Orchestration command invariant failed (thread.create): Thread '<id>' already exists and cannot be created twice.

So the user sees an actionable git error once, then a permanent and unrelated-looking invariant error forever after — which makes the real cause very hard to find. From my orchestration_events, five threads were created and deleted within 50–110 ms each, every one with exactly two events (createddeleted), and all four rejected commands in the database are that same invariant error.

The wedge itself is tracked in #4647 (the ArionStudio comment there describes this same missing-origin trigger, but it is not tracked as its own defect). #2148 is the sibling precondition gap for commitless repositories. This issue is specifically about T3 offering an unsatisfiable option in the first place.

Impact

Blocks work completely

Version or commit

Reproduced against main at 7537adc (2026-08-04). Originally encountered on the T3 Code nightly client.

Environment

macOS (Apple Silicon), local-only Git repository with 5 commits on main and no configured remotes.

Logs or stack traces

Git command failed in GitVcsDriver.fetchRemote (/…/<project>): git fetch origin failed

Followed on every retry by:

Orchestration command invariant failed (thread.create): Thread '55eae931-…' already exists and cannot be created twice.

Workaround

Turn off "Start from origin" (the control changes from "From origin/main" to "From main"), or use "Current checkout" instead of "New worktree", or add a real remote to the repository. Note the workaround only helps future sends — a draft already burned by a failed attempt stays wedged per #4647 until a new draft is minted.

Suggested fix

Gate the "Start from origin" affordance on the presence of a remote, and treat startFromOrigin as recoverable server-side — fall back to the local base ref rather than failing the entire bootstrap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions