Skip to content

fix(server): a Claude command you stop shows as interrupted - #14708

Closed
SunkenInTime wants to merge 2 commits into
pingdotgg:mainfrom
SunkenInTime:fix/v2-claude-interrupted-tools
Closed

SunkenInTime wants to merge 2 commits into
pingdotgg:mainfrom
SunkenInTime:fix/v2-claude-interrupted-tools

Conversation

@SunkenInTime

@SunkenInTime SunkenInTime commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Problem

When you stop a Claude turn while a command is running, the command is saved as failed. The run and the provider turn are correctly interrupted. Codex, Pi and (since #13806) Cursor record a stopped command as interrupted.

What it looks like

Stopped Claude command, before and after

The visible difference is small: the stopped command's terminal icon is red ("failed") before this change and grey ("interrupted") after. That matches how Codex, Cursor and Pi show a stopped command. Agents reading the thread with t3_thread_read see the same status, so before this change they were told the command failed.

Full screenshots and the Stop interaction

Same prompt on a dev build of this branch, using Claude Haiku 4.5 on Windows. The thread runs a 60-second node command through the Bash tool, and I press Stop about 25 s in. For the "before" run I swapped in ClaudeAdapterV2.ts from the current base, which is slightly newer than this PR's base. The only change that matters here is the finalizeActiveTurn status.

Before After
before after
before gif after gif

The projection rows for those two threads have command_execution with status failed before and interrupted after.

Evidence

Seen on my V2 install (Windows 11, T3 Code Alpha 0.0.43-preview.20260925.2234). Two Claude runs I stopped mid-command, cb27a173… run 1 and 25318ad4… run 1, show their in-flight tool items (toolu_01Dsw5XiGCxQMvQetAYPoZJJ, toolu_015FxSiZtU3XTHWstWE8Tr56) as failed. A Codex run stopped the same way on the same day (bbd82247…, exec-ca9958dc) shows interrupted.

The recorded turn_interrupt_mid_tool Claude fixture asserted this behavior: commandItem.status === "failed".

Change

finalizeActiveTurn in ClaudeAdapterV2 closes every tool that never got a result. It always closed them as failed. Now an interrupted or cancelled turn closes them with its own status. Tools on a turn that ends on its own stay failed, as before.

Scope and approval

Very small, focused fix for an obvious status bug: one line in the Claude adapter plus the three fixture assertions that encoded the old status, mirroring #13806 for Cursor. Julius asked for last small V2 bug fixes before the nightly merge.

Verification

  • turn_interrupt_mid_tool/claude_output.ts now asserts commandItem.status === "interrupted". vp test run src/orchestration-v2/testkit/OrchestratorReplayFixtures.integration.test.ts -t turn_interrupt_mid_tool:
    • Before the fix: expected 'failed' to equal 'interrupted' (1 failed, 3 passed).
    • After: 4 passed.
  • claude_background_task_interrupt/output.ts and turn_interrupt_restart/claude_output.ts asserted the same old failed status for a stopped command and now expect interrupted. The full OrchestratorReplayFixtures.integration.test.ts: 121 passed.
  • vp test run src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts: 124 passed, 1 failed. The failure, "names an expired Claude login instead of the terminal API error" (expected 'Claude could not authenticate…' to include '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/synthetic/project'), fails identically on the base without this change.
  • vp exec tsc --noEmit -p . in apps/server: no error TS. vp lint on the touched files reports only the existing unused layer warning at the end of ClaudeAdapterV2.ts.
  • Live Claude stop before and after the fix, shown above.

Diagnosed and implemented by Claude Opus 5.5 in Claude Code, running inside T3 Code.

🤖 Generated with Claude Code

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 2, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Would Approve

Macroscope's review found this PR approvable — This focused fix changes only Claude tool-finalization status for interrupted turns and updates targeted interruption tests; completed-turn behavior remains unchanged. A separate unresolved High-severity orchestration-contract finding remains an independent blocking risk outside this diff.

Not approved because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 2, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 2, 2026 03:35

Dismissing prior approval to re-evaluate dd4d8f3

@github-actions github-actions Bot added size:S 10-29 changed lines (additions + deletions). and removed size:XS 0-9 changed lines (additions + deletions). labels Oct 2, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 2, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 2, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 2, 2026 05:27

Dismissing prior approval to re-evaluate dd4d8f3

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 2, 2026
@juliusmarminge
juliusmarminge deleted the branch pingdotgg:main October 2, 2026 19:23
@juliusmarminge juliusmarminge added the triage:keep-open Keeps this PR open despite not necessarily passing the contribution guide fully label Oct 2, 2026
@juliusmarminge juliusmarminge reopened this Oct 2, 2026
@juliusmarminge
juliusmarminge changed the base branch from t3code/codex-turn-mapping to main October 2, 2026 20:37
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 2, 2026 20:38

Dismissing prior approval to re-evaluate dd4d8f3

SunkenInTime and others added 2 commits October 2, 2026 13:43
When a Claude turn ended with tools still open, finalizeActiveTurn closed
every one as failed, so stopping a turn mid-command recorded the command
as failed. Codex, Pi and (since pingdotgg#13806) Cursor record it as interrupted.

Close open tools with the turn's own status when the turn was stopped or
cancelled; a turn that ends on its own still leaves them failed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ommands

claude_background_task_interrupt and turn_interrupt_restart asserted the
old failed status for the command a stop cut short.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
}),
/** Provider acceptance of a mailbox delivery; distinct from the agent reading its result. */
Schema.Struct({
type: Schema.Literal("notification.delivery.accept"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High src/orchestrationV2.ts:2674

Clients can submit server-only lifecycle and delivery commands through dispatchCommand, allowing them to acknowledge or dispose delegated results, release or fail preparing runs, and forge thread.created.record history. This can permanently suppress delegated-task delivery, start unprepared workspaces, terminate another launch, or corrupt agent-visible history. Keep notification.delivery.accept, prepared-run.release, thread.created.record, delegated_task.completion-delivery.acknowledge, delegated_task.completion-delivery.dispose, and prepared-run.fail out of OrchestrationV2Command and include them only in the internal/server-only union, or require an unforgeable worker capability.

🤖 Copy this AI Prompt to have your agent fix this:
In file @packages/contracts/src/orchestrationV2.ts around line 2674:

Clients can submit server-only lifecycle and delivery commands through `dispatchCommand`, allowing them to acknowledge or dispose delegated results, release or fail preparing runs, and forge `thread.created.record` history. This can permanently suppress delegated-task delivery, start unprepared workspaces, terminate another launch, or corrupt agent-visible history. Keep `notification.delivery.accept`, `prepared-run.release`, `thread.created.record`, `delegated_task.completion-delivery.acknowledge`, `delegated_task.completion-delivery.dispose`, and `prepared-run.fail` out of `OrchestrationV2Command` and include them only in the internal/server-only union, or require an unforgeable worker capability.

@juliusmarminge
juliusmarminge force-pushed the fix/v2-claude-interrupted-tools branch from dd4d8f3 to 43c8347 Compare October 2, 2026 20:58
@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Only developers with an assigned seat can use this organization's usage-based review budget, and seats here are assigned manually. Ask an admin to assign a seat, or change the review continuation mode in Billing.

Next included review available in 42 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 59bc54bc-49fa-42e6-a479-d7c43756e1a9

📥 Commits

Reviewing files that changed from the base of the PR and between cc1e634 and 43c8347.

📒 Files selected for processing (4)
  • apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
  • apps/server/src/orchestration-v2/testkit/fixtures/claude_background_task_interrupt/output.ts
  • apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/claude_output.ts
  • apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_restart/claude_output.ts
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:S 10-29 changed lines (additions + deletions). triage:keep-open Keeps this PR open despite not necessarily passing the contribution guide fully vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants