# \[Bug\]: Claude Steer waits for a running Bash command to finish instead of reaching the agent · Issue \#15720 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/15720)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: completed

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/15720)

---

### Before submitting

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

### Area

apps/server

### Steps to reproduce

1. Set **Settings → General → Follow-up behavior** to **Steer**.
2. In a Claude thread, ask the agent to run a command that keeps running in the foreground. Claude Code refuses a bare `sleep`, so I used `curl` against a local endpoint that does not answer.
3. While the command runs, send: `Change of plan: stop waiting for that command and reply with exactly STEERED_NOW.` It shows in the thread as a steer.
4. The agent does not react. It answers `STEERED_NOW` only after the command returns.

I scripted these steps against a fresh server and a disposable Git project, sending the same `message.dispatch` (`steer_active`) command as the web client, and kept the command running for 60 s after the steer reached the CLI: [repro-steer-wait.ts](https://gist.github.com/nekohasekai/fd80f04cd4d6c415bebddb32693c2cc0). Results on `claude-sonnet-5-5`:

| When the steer reached the CLI | What Claude did | Agent answered the steer |
|---|---|---|
| 4.2 s after the `tool_use`, after `task_started` | Kept the steer queued until the command returned | 61.8 s after the steer, right after the script released the command at 60 s |
| 0.74 s after the `tool_use`, 2.9 s before `task_started` (`--early`) | Same | 65.1 s after the steer |
| 0.11 s after the `tool_use` (`--early`) | Cancelled the call before it started (`Command was aborted before completion`) | 1.2 s after the steer |

The web recording below shows the first case: the steer is answered 35 s after it was sent, only after the command is released.

I first hit this with a slow scan that ran for about 8 minutes. A steer sent 4.4 minutes in was read only when the process was killed from outside, 3.5 minutes later.

### Expected behavior

Steer reaches the agent right away, as the composer docs describe ("steer the running turn immediately") and as it does for Cursor since V2 (#14585). In Claude Code itself, the way to do this is Esc, then send: the running command is interrupted and the new message is read at once.

### Actual behavior

For Claude, Steer behaves like Queue whenever the agent is inside a running command. The thread shows the message as steered immediately, but Claude reads it only after the command returns, however long that takes.

What happens, from the provider log:

- `ClaudeAdapterV2.steerTurn` only offers the message to the Claude CLI with `priority: "now"`. It does not interrupt the turn.
- Claude Code does not interrupt a running Bash call for a `now` message. The message waits in its queue and is folded in after the call returns.
- **Correction to #15708:** there I wrote that a steer arriving before `task_started` (about 3 s in) aborts the call. That is not the boundary. In the second row above, the steer arrived before `task_started` and still waited. Only a steer that arrives within a fraction of a second, before the command has started, cancels the call. A user cannot type a follow-up that fast, so in practice the steer always waits.

Offering the message and then interrupting the turn, in the same CLI process, does what Esc then send does. I checked this directly against the Agent SDK (`esc-then-send.ts` in the same gist): `prompt.offer` with `priority: "now"`, then `query.interrupt()` without `query.close()`. The command was aborted at once, the queued message ran next, and the agent answered `STEERED_NOW` 1.1 s after the offer, in the same session. Without the interrupt, which is what T3 does today, it waits for the command as in the first two rows above.

Before V2, #12541 made Claude's Steer interrupt the running turn first, and was closed with "if it's still a bug when v2 lands feel free to re-file". This is that re-file against V2.

This is also the wait in which #15708 happens: a user who sees no reaction to a steer presses Stop, and the steer that was still queued is lost. A steer that interrupts the command would be read before that.

### Impact

Major degradation or frequent failure

### Version or commit

main @ 4ee6bfd50e. First seen on Nightly 0.0.46-nightly.20261004.2644.

### Environment

macOS 27.0.1, Node 26.9.0, Claude Code 2.1.289, `@anthropic-ai/claude-agent-sdk` 0.3.276. Seen with `claude-opus-5-5` and reproduced with `claude-sonnet-5-5`.

### Logs or stack traces

```shell
# repro-steer-wait.ts, steer after task_started (outgoing = server to CLI)
17:23:39.212 in  {"type": "assistant", "content": ["tool_use:Bash"]}
17:23:42.296 in  {"type": "system", "subtype": "task_started", "task_type": "local_bash", "is_backgrounded": false}
17:23:43.400 out {"type": "prompt.offer", "content": "Change of plan: stop waiting for that command an…", "priority": "now", "uuid": null}
             (nothing for 61 s; the script releases the command at 17:24:44.4)
17:24:44.440 in  {"type": "user", "content": ["tool_result:GATE_OPEN"]}
17:24:44.451 in  {"type": "command_lifecycle", "state": "cancelled", "command_uuid": "e4080d38…"}
17:24:46.163 in  {"type": "assistant", "content": ["text:STEERED_NOW"]}

# esc-then-send.ts, same setup through the Agent SDK, seconds since start
 7.49 in  {"type": "system", "subtype": "task_started"}
 9.49 out prompt.offer with priority "now", then query.interrupt() -> {"still_queued": []}
 9.50 in  tool_result "The user doesn't want to proceed with this tool use. …"
 9.51 in  {"type": "result", "subtype": "error_during_execution", "terminal_reason": "aborted_tools"}
10.61 in  {"type": "assistant", "content": ["text:STEERED_NOW"]}   same session_id, query never closed
```

### Screenshots, recordings, or supporting files

https://github.com/user-attachments/assets/e87bdf2b-6b2c-4a84-a60f-a7921c7cab39

The web client against a fresh dev server and a demo project, with Claude Sonnet 5.5 and Follow-up behavior set to Steer. The recording script overlaid the yellow captions; they do not change the app. The agent's command is `curl` against a local endpoint that answers only when the script releases it.

[Gist](https://gist.github.com/nekohasekai/fd80f04cd4d6c415bebddb32693c2cc0) with both scripts. Save `repro-steer-wait.ts` as `apps/server/scripts/repro-steer-wait.ts` and run `node apps/server/scripts/repro-steer-wait.ts`, or add `--early` to steer as soon as the command shows as running. It uses the existing Claude CLI login and keeps the server log, provider log and projection in the directory it prints. `esc-then-send.ts` needs only `@anthropic-ai/claude-agent-sdk` and the Claude CLI.

### Workaround

Press Stop, then send the message again. Because of #15708, a steer already sent before Stop is lost, so it has to be sent again.

