Repository navigation
Conversation
Stop holds the queue behind the run it interrupts. A message sent afterwards started at once on the idle thread but left the held messages held, so they never ran, and the web queue gave no sign they were paused. A new message a person sends from web or mobile now releases the held queue, so those messages follow it. Scheduled prompts, re-sent late steers, and other automatic sends keep the hold, as do messages waiting on a worktree that was never created. The web queue header and mobile queue sheet say when the queue is paused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| const worktreeMissing = | ||
| (latestRun?.status === "failed" || latestRun?.status === "interrupted") && | ||
| latestRun.workspacePreparation?.type === "worktree" && | ||
| projection.thread.worktreePath === null; |
There was a problem hiding this comment.
🟠 High orchestration-v2/Orchestrator.ts:5225
After a failed worktree preparation and an intervening turn, this code releases all held runs even though thread.worktreePath is still null; those runs then execute in the project checkout instead of the intended worktree. worktreeMissing only checks latestRun, so the completed intervening run hides the failed preparation; preserve that hold while any failed or interrupted worktree preparation remains unresolved.
- const worktreeMissing =
- (latestRun?.status === "failed" || latestRun?.status === "interrupted") &&
- latestRun.workspacePreparation?.type === "worktree" &&
+ const worktreeMissing =
+ projection.runs.some(
+ (run) =>
+ (run.status === "failed" || run.status === "interrupted") &&
+ run.workspacePreparation?.type === "worktree",
+ ) &&
projection.thread.worktreePath === null;🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration-v2/Orchestrator.ts around lines 5225-5228:
After a failed worktree preparation and an intervening turn, this code releases all held runs even though `thread.worktreePath` is still `null`; those runs then execute in the project checkout instead of the intended worktree. `worktreeMissing` only checks `latestRun`, so the completed intervening run hides the failed preparation; preserve that hold while any failed or interrupted worktree preparation remains unresolved.
ApprovabilityVerdict: Would Approve Macroscope's review found this PR approvable — This is a narrowly scoped queue-continuation bug fix with targeted regression coverage and presentation-only client/documentation updates. An unresolved High finding identifies a worktree-safety edge case in the new release guard, so that correctness risk remains blocking under the repository threshold. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
|
Note This comment is posted by Julius' dot Closing because a new send now resumes previously held work after Stop, failure, or restart, changing the existing explicit Resume workflow. #18805 has no maintainer approval for that change, which the prior-approval rule requires. The misleading queue label is a useful bug report. Please agree on the resume behavior with maintainers first, or submit the paused-state visibility fix while preserving the current hold behavior. |
Problem
After Stop, messages queued behind the stopped run are held so that nothing restarts on its own. If you then send a new message, it starts at once, but the held messages stay held. When the new turn ends, the queue never drains, because the next-message check skips the queue while anything is held. Steer is disabled because nothing is running, and the web queue just says "Queued", so nothing tells you the message is paused or that Resume in an empty composer is the way out. Fixes #18805.
Change
Surfaces: the server rule applies to every client. Web and desktop share the header; mobile has its own banner. Providers are unaffected: the hold lives in orchestration, not in an adapter.
Scope and approval
Bug fix for #18805 (filed with the event log from the affected thread). Stop's hold is intended, but the hold had no exit when a person kept working. The fix gives sending the same effect as pressing Resume, and leaves the hold on every automatic path.
Verification
vp test run apps/server/src/orchestration-v2/ThreadStop.test.ts: 14/14 pass. Five tests are new: a client send after Stop releases the held queue; a scheduled prompt doesn't; a re-sent late steer doesn't; messages held behind a worktree that was never created stay held. I disabled each guard in turn and confirmed its test fails without it.tscpasses forapps/server,apps/webandapps/mobile, and lint and format pass on the changed files.sleep 90turn, queued a message, and pressed Stop, and the queue showed Paused. Then I sent a new message. The header switched to Queued straight away. The new run completed, and the released message started 0.4 s later and completed, with no Resume.Before (
main): held after Stop, but shown as "Queued"After: the same held queue, shown as "Paused"
The before shot uses the same held state, with the old label restored through hot reload.
Not checked: the mobile banner on a device (copy-only change, typechecked), and a Claude thread (the hold and release are provider-independent).
Models