Skip to content

[Bug]: pi — a steer behind a long-running Bash command is marked steered, then the thread emits nothing for minutes #33776

Closed

Description

@ProphetOfDoom-PoD

Before submitting

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

Area

apps/server

Steps to reproduce

  1. Use a thread on the pi adapter (not a Claude thread), with Settings › General › Follow-up behavior set to Steer.
  2. Let the agent start a foreground Bash tool call that blocks for minutes — in my case a poll loop of the shape sleep 540; date -u; <poll command>.
  3. While that call is still blocked, send a follow-up (text plus an image).
  4. Watch the thread until the blocked command returns.

Expected behavior

Either of these would be enough:

  • Until the agent has actually taken the message, say so — e.g. the marker reads "waiting for the agent to read this", and only flips to "Steered the active turn" once it has been read. Right now the marker means "offered", not "delivered".
  • Keep the blocked command looking alive (elapsed time, a heartbeat, partial stdout), so "my message is waiting behind a command" can be told apart from "the thread is hung".

Actual behavior

The message is marked steered immediately, and the thread then emits nothing at all until the blocked command returns. Event log for the thread (relative clock, t+0 = the send):

t+0:00.0              send: text + image. A foreground Bash call is already blocked
                      (`sleep 540; date -u; <poll command>`).
t+0:05.1              server creates a run for the message, then cancels it before start
                      (status=cancelled, startedAt=null) and re-attaches the message to
                      the live run as a steered user_message turn item, written with
                      status=completed.
t+0:05.1 → t+1:38.8   zero events for this thread. 93.7 s of nothing.
t+1:38.8              the blocked command returns; command_execution starts streaming.
t+2:17.1              one short follow-up command completes.
t+2:42.5              assistant reply that reads the steer (same run).
t+2:52.4              run completes.

So the message does land — 2 m 42 s after it was sent, at the next step boundary. What is missing is any state between "offered" and "read". From the outside the thread is indistinguishable from a hung session, and the natural reaction is Stop + resend, which drops the unread steer (#15708) — that is how the duplicate sends in this thread started.

On the pi adapter I could not find a delivery/acknowledgement event for the steer at all: the only trace is the user_message turn item, which is completed at offer time, before the model has seen it. This looks like the pi-side counterpart of #23948, whose diagnosis is Claude-specific (tool_progress heartbeats stop after a priority: "now" offer), so it does not explain the pi path.

Impact

Major degradation or frequent failure

Version or commit

T3 Code desktop 0.1.7 (Beta), Windows x64; server 0.1.7.

Environment

Windows x64 desktop app; pi adapter with a third-party OpenAI-compatible model configured as a provider instance (not Claude, Codex, Cursor or Grok); Follow-up behavior = Steer. The normal working pattern here is sleep-then-poll Bash loops, so multi-minute blocked tool calls are routine rather than pathological.

Logs or stack traces

blocked call   sleep 540; date -u; <poll command>     ~9 min
next call      date -u; <inspect command>             ~2 s

No stack traces: the timeline above is the whole signal. Workspace paths, repository names and command bodies are redacted.

Related observation (possibly a separate bug)

In the same thread an earlier turn ran 83 minutes. Sends during it resolved two different ways: three became runs that were created and stayed queued (the oldest was still queued 80 minutes later, so it will execute long after it was written), while other sends in the same window were folded into the live turn as steers. Both paths coexisting in one thread may be #23271 / #23403.

Workaround

None clean. Pressing Stop ends the blocked turn and lets the next turn start, but drops the unread steer (#15708). Switching Follow-up behavior to Queue gives each send its own run, but the send then waits for the whole turn — 83 minutes, in the case above.

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

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