fix(server): unpushed branch no longer breaks thread creation - #7610
fix(server): unpushed branch no longer breaks thread creation#7610DraftProducts wants to merge 1 commit into
Conversation
Starting a thread with "start from origin" enabled ran `git fetch origin`
and then resolved `refs/remotes/origin/<baseBranch>`. A base branch that was
never pushed has no remote-tracking ref, so `git rev-parse --verify` exits
non-zero and the whole bootstrap fails.
The failure is not recoverable from the client. The rollback dispatches
`thread.delete`, which soft-deletes the thread but leaves its event stream in
place, so `requireThreadAbsent` keeps rejecting the retry:
Orchestration command invariant failed (thread.create):
Thread '<id>' already exists and cannot be created twice.
Each retry carries a fresh commandId, so receipt idempotency never dedupes it
either, and the surfaced error hides the underlying git failure entirely.
Repos with no origin remote already fall back to the local base branch. Do the
same when the remote-tracking ref is missing.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a straightforward bug fix that adds graceful fallback handling when a branch hasn't been pushed to remote. The production code change is minimal (~9 lines), with clear intent documented in comments, and includes a comprehensive test covering the scenario. You can add or adjust custom eligibility rules. Learn more. |
What Changed
dispatchBootstrapTurnStartnow treats the remote-tracking lookup as optional.When
resolveRemoteTrackingCommitfails, the worktree is cut from the local basebranch instead of taking down the whole bootstrap. Repos with no
originremotealready behave this way; this extends the same fallback to a base branch that has
no remote-tracking ref.
Tests: new bootstrap case in
server.test.tsfor a base branch with noremote-tracking ref, asserting the worktree is cut from the local branch and that
no
thread.deleteis dispatched — the rollback is what burns the thread id. Fullapps/serversuite (2611 passing) plus every other package, typecheck, lint, andformat pass. The two failures in the repo (
ProviderRegistrycodex re-probe andNet.findAvailablePort) reproduce onmainand are untouched by this change.Why
Creating a thread on a local-only branch with "start from origin" enabled fails,
and every retry then fails differently:
That invariant error is a red herring. Bootstrap runs
git fetch originand thenresolves
refs/remotes/origin/<baseBranch>. A branch that was never pushed has noremote-tracking ref, so
git rev-parse --verifyexits non-zero and the wholebootstrap fails. The rollback dispatches
thread.delete, which soft-deletes thethread but leaves its event stream in place, so
requireThreadAbsentrejects theretry. Each retry carries a fresh commandId, so receipt idempotency never dedupes
it either. The thread id is burned for good, and the git failure that started it
never reaches the user.
Falling back is the right call rather than surfacing the git error: "start from
origin" is a stored default rather than something chosen per thread, so honoring
it only when a remote base exists matches what the no-remote path already does.
Not addressed: any other bootstrap failure still rolls back into the same
unusable state. Making a soft-deleted thread id reusable is a decision about the
event-sourcing invariant, not this fix.
Checklist
Changes by Claude Opus 5 running in Claude Code.
Note
Medium Risk
Changes bootstrap git/worktree resolution for thread creation; wrong fallback could point worktrees at unexpected refs, though scope is limited to the optional remote-tracking path.
Overview
Fixes thread bootstrap failing (and burning the thread id on retry) when start from origin is enabled but the chosen base branch has no
origintracking ref.In
dispatchBootstrapTurnStart, afterfetchRemote,resolveRemoteTrackingCommitis now wrapped inEffect.option. On success, the worktree still bases off the remote commit SHA; on failure,worktreeBaseRefstays on the localbaseBranch(same behavior as repos withoutorigin).Adds a
server.testcase that stubs a failed remote-tracking resolve and assertscreateWorktreeis called with the local branch asrefNamewhile bootstrap commands complete without rollback.Reviewed by Cursor Bugbot for commit 490657a. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix thread creation when base branch has no remote-tracking ref
When
startFromOrigin=trueand the base branch has no remote-tracking ref,resolveRemoteTrackingCommitnow usesEffect.optionso a failure returnsNoneinstead of aborting. If no remote-tracking commit is found,worktreeBaseRefis left unchanged andcreateWorktreefalls back to the local base branch.Macroscope summarized 490657a.