Skip to content

Grok turns held open by stalled background subagents show no waiting state, and steering only supersedes attempts #17159

Open

Description

@Mkassabov

What happened

threads seem to just stall; they will go minutes on end without outputting anything and when you steer the agent it says something completed 10 minutes ago and it never started the next thing … sometimes queues just dont send message when an agent is idle

New user on Nightly, desktop app plus the Android app over Tailscale, Grok provider. Threads look idle (the agent has answered) but stay "working" for up to an hour. Steering doesn't unstick them, and queued messages don't send.

Diagnosis

When a Grok turn spawns background subagents, AcpAdapterV2 keeps the root turn open after session/prompt returns (deferFinalizeForBackgroundWork: true in GrokAdapterV2.ts) until every subagent ends. That's intended. But if a subagent's model stream stalls, the only thing that ends the hold is the Grok CLI's own 3600 s inference idle timeout. For that whole time:

  • The UI gives no sign that the turn is waiting on subagents. The answer is on screen and the thread still says "working".
  • Steering interrupts and restarts the attempt (steering_restart). The new attempt replies in seconds and then hits the same hold. Each completed attempt is marked superseded and folded away, so steering makes history look like it's disappearing, without ever releasing the hold.
  • Queued follow-ups stay queued, because the run still counts as active.

In the observed thread, run 17 went through 6 attempts over 62 minutes. Its two subagents had sent inference requests at 08:50:44 and 08:51:47 that never received a chunk. Grok ended them at 09:51:51 (idle_timeout), and the run finalized at 09:51:58. Full timeline is in #15489.

Steps to reproduce

  1. Grok provider (seen with a custom-gateway model; any model stream that stalls should do).
  2. Ask for work that makes Grok spawn_subagent in the background.
  3. Have a subagent's inference stall: no chunks and no error (for example, a gateway that holds the connection open).
  4. The root agent finishes its reply. The thread stays "working".
  5. Steer: a new attempt starts, replies, and holds again. The previous attempt folds as "Superseded attempt".
  6. Queue a follow-up: it doesn't send until the subagent dies (up to 1 h).

Version

0.0.46-nightly.20261008.2813 (30cc788)

Environment

Linux x64 (CachyOS, kernel 7.1.8), Node 26.8.2, T3 desktop app (AppImage) plus the Android app over Tailscale; Grok CLI 1.0.46 (2765805b9442)

Evidence

# Grok unified.jsonl (subagent)
08:50:44.259Z shell.turn.inference_start {"loop_index":10}
09:51:51.297Z shell.turn.inference_failed {"kind":"idle_timeout","message":"inference idle timeout after 3600s with no chunks"}
09:51:54.484Z subagent failed {"success":false,"cancelled":false}
# Grok unified.jsonl (root, attempt 5)
09:32:20.133Z shell.handle_prompt.done {"prompt_id":"t3-xai-prompt-5","ok":true}
# T3: provider turn 21 started 09:32:05, last item 09:32:20, held until steered at 09:50:04
# orchestration_v2_projection_subagents: both rows status=running 08:50:08 → failed 09:51:55

Related issues

#15489: same symptom. Its open question (why the turn stayed open) is answered with the trace in a comment there. This issue is the product ask: surface the hold and don't let steers supersede held attempts. #15888: a Grok delegated child stays running. #16987: queued messages missing or reordered. PR #17144: Grok runs finishing when background commands end (a different hold source).

Fix applied or workaround

None applied. Workaround: when a thread looks stuck after an answer, check for running subagents and cancel them instead of steering.

Filed by

Claude Code (Opus 5.5) via t3 triage

Activity

  1. ivanfenenko commented on Oct 12, 2026

    @ivanfenenko

    Additional repro of the same visible hold. The rows that kept the run open were exited background shells, and this thread has no subagents.

    What happened

    The reply was on screen and Grok had ended the turn, but the thread stayed Working. The next message queued and did not send. Force steer was required to continue.

    Diagnosis

    This is the deferFinalizeForBackgroundWork hold: the prompt has settled and the answer is visible, while background work still looks running, so the run stays active. The sidebar keeps saying Working, and a normal send queues behind it.

    The projection for this thread has zero subagent rows. Five background command_execution tools stayed running after their processes had exited. Grok's event log never records task_completed, and it never mentions task ids 01a12f85, 01a12f87, or 01a12f89. Those shell tool calls are recorded complete 3–10 ms after launch, which is the background-launch acknowledgement.

    Force steer released the hold. It interrupted the five tools and the provider turn, cancelled the queued run, and the restarted attempt then completed the original run. In the stalled-subagent report above, steer only supersedes the attempt and the hold stays until the subagent dies.

    The user-visible failure matches this issue: no waiting state, and the queued follow-up does not send. The work being waited on matches the command-end gap in #15888 / #17144. One extra fact for that gap: the Grok log has no task_completed, TaskOutput, MultiResult, or KillTask event for these tasks, so a parser of those signals had nothing to read. #17144 is still open, so that change is not in this nightly.

    On main, the 60 s background-hydration safety force-completes tools that are still awaiting hydration. A tool already tracked as running stays running. Those line references are from a local main checkout and may differ from this nightly binary.

    Steps to reproduce

    1. Desktop Nightly, Grok, model grok-4.7-build-fast.
    2. In one turn, background two Gradle unit-test runs and three xcodebuild test runs (launch and do not wait). Observed launches: 09:50:50Z, 09:50:50Z, 09:52:59Z, 09:52:59Z, 09:54:39Z.
    3. Wait until the processes exit. The Gradle log's last write is 09:53:30Z and it ends BUILD SUCCESSFUL. The xcodebuild log's last result is ** TEST SUCCEEDED ** at 09:55:50Z (118 tests). That file is not written after 09:55:55Z.
    4. Let the turn finish its reply.
    5. The thread stays Working. Send a follow-up: it queues.
    6. Force steer.

    Version

    0.0.46-nightly.20261009.2873

    Environment

    macOS 26.5.2 (25F84). T3 Code (Nightly) desktop app, local server. Model grok-4.7-build-fast. Grok CLI on PATH at report time: 1.0.50 (c58f321264ba).

    Evidence

    Thread 7932ec94-25d9-4266-9e86-4ec5fd33373b. Times are UTC.

    • Grok turn_ended outcome=completed at 2026-10-12T10:19:55.911Z.
    • Provider event log, 30 ms later: session/prompt status=failed errorTag=Interrupt at 2026-10-12T10:19:55.941Z.
    • Runs 1–3 completed within about a second of their own turn_ended (09:01:05Z, 09:07:06Z, 09:11:29Z). Run 4 stayed open.
    • Run 4 requested 2026-10-12T09:12:12.885Z. Provider turn 4 closed interrupted at 2026-10-12T10:21:24.658Z, the steer. Run 4 itself completed after the restarted attempt, at 2026-10-12T10:25:54.223Z. Attempt 1 is superseded. Attempt 2 is completed.
    • Run 5, the queued follow-up, requested 2026-10-12T10:20:37.326Z and was cancelled at 2026-10-12T10:21:24.643Z.
    • Five [bg] command_execution rows, all interrupted at 2026-10-12T10:21:24.657Z–.658Z:
      • 09:50:50.394Z Gradle unit tests, task 01a12f85
      • 09:50:50.429Z xcodebuild tests, task 01a12f85
      • 09:52:59.558Z Gradle unit tests, task 01a12f87
      • 09:52:59.589Z xcodebuild tests, task 01a12f87
      • 09:54:39.037Z xcodebuild tests, task 01a12f89
    • orchestration_v2_projection_subagents count for this thread: 0.

    Related

    #15888 and #17144 cover background commands holding a Grok run after they end. #15489 is the same symptom with a weaker cause. This trace is only on this issue.

    Workaround

    Force steer unstuck this thread. The shells were already dead, and only the projection was still running. There were no subagents to cancel.

    Filed by

    Grok (grok-4.7-build-fast) via T3 Code triage.

  2. added
    needs more infoInitial triage showed no bug. Awaiting more info
    and removed
    needs more infoInitial triage showed no bug. Awaiting more info
    on Oct 21, 2026
  3. djodjonx commented on Oct 22, 2026

    @djodjonx

    Another repro of the exited-background-shell hold, this time on a delegate_task child, where it also blocks the parent orchestrator.

    Setup. T3 Code Beta 0.1.0, Grok CLI 1.0.67, grok-4.7-build-fast, macOS. A Claude parent thread delegates to a Grok child with delegate_task (mode: "async", isolation: "shared") and ends its turn, waiting for the completion notification. No subagents in the child.

    What happens. The child's Grok turn runs one terminal command that goes to the background (auto-backgrounded after ~30 s). Grok finishes the prompt, but the T3 run stays running, so the parent is never notified and the whole pipeline waits until someone types in the child thread.

    Timeline for one child (Grok session 01a162d7…, times UTC, from ~/.grok/logs/unified.jsonl and t3_thread_read):

    Time Event
    09:00:33 T3 run ordinal 1 requested
    09:14:19 shell.task_wake.actor_admission + bridge_admission for the background command, shell.prompt.start_blocked reason=task_already_running queue_depth=2
    09:17:30 final assistant message, shell.handle_prompt.done prompt_id=t3-xai-prompt-1 ok=true
    09:17 → 09:34 nothing in either log; run still running, parent not notified
    09:34:02 user message to the child → t3-xai-prompt-2
    09:38:12 run ordinal 1 marked completed, reported startedAt 09:35:35

    An explicit kill does not release it either. In another child (session 01a16206…), the command was auto-backgrounded, then killed by the model with kill_command_or_subagent (shell.task_wake.suppressed explicitly_killed=true kill_result_delivered=true). handle_prompt.done ok=true at 05:18:22; the run stayed running until a user message at 06:19.

    Pattern over two days of delegated Grok children:

    Grok session Background command / task-wake events Run held after handle_prompt.done
    01a162d7 admission + queued wake yes, ~17 min
    01a15f1f 3 admissions, 1 suppressed, an extra task-completed-… prompt yes, ~30 min
    01a16206 auto-backgrounded at 30 s, then explicitly killed yes, ~1 h
    01a15f12, 01a1629b and the other writers that day none no

    Every held run had a background command, and no run without one was held. This is a correlation from the logs only: I have not stepped through the adapter.

    Expected. Once Grok reports the T3 prompt done, a background shell that has exited, or that was killed, should not keep the run open. For delegated tasks, the parent's completion notification should fire.

    Workaround we use meanwhile. The parent waits with a timeout, and treats the child as done when the child's report file exists or its last message is final and idle. Child briefs forbid background commands.

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