Skip to content

Subagent stream dies silently on transient network failure — no retry/reconnect, watchdog kills after 600s of silence #87987

Description

@valaquet

Bug: subagent stream dies silently on transient network failure — no retry/reconnect, watchdog kills after 600s

Environment

  • Claude Code: 2.1.233 (also reproduced on earlier 2.1.x builds over the past several days)
  • OS: Windows 11 Home 10.0.26200
  • Model: claude-fable-5
  • Setup: interactive session dispatching multiple parallel subagents via the Agent tool (some with isolation: worktree), machine awake and actively executing tool calls the whole time (this is NOT the laptop-sleep case of the now-closed Subagents killed by stream-idle watchdog when host laptop sleeps #53695)

Symptom

Subagents die with:

Agent stalled: no progress for 600s (stream watchdog did not recover)

15 occurrences in a single session (2026-08-19, ~10:00–14:00 UTC), all in the middle of active work. In every case the subagent transcript (JSONL) shows the identical shape:

  1. last event: a tool_result is delivered to the model (Read/Edit/Bash/Glob results — normal, fast tool calls), or in two cases the session-start attachments (the model never produced its first token),
  2. then exactly 600 s of zero stream events,
  3. then the watchdog kill ([Request interrupted by user] injected, task-notification "Agent stalled…").

So the failing step is always the next API streaming request after a completed tool call: it either never connects or dies before the first event, and nothing ever retries it.

Evidence of the underlying transient network failures

The parent session's JSONL for the same time window contains system/api_error records that the main loop logged and recovered from via retry:

10:17:37Z  Connection error.  "Connection refused — a firewall or proxy may be blocking it (ConnectionRefused)"  isNetworkDown: true
11:15:12Z  Request timed out.
11:31:58Z  Connection error. (ConnectionRefused)
11:47:44Z  Connection error. (ConnectionRefused)
12:23:29Z  Request timed out.
12:30:33Z  Connection error. (ConnectionRefused)
13:37:56Z  Request timed out.

Subagent stall timestamps interleave/correlate with these, e.g. a subagent's very first API call stalled at 12:30:02Z — ~30 s around the 12:30:33Z ConnectionRefused in the parent. Stalls also cluster across independent subagents to within seconds, which rules out per-agent behavior and points to a shared network-path fault:

  • 10:33:58Z / 10:34:53Z / 10:36:45Z — three different subagents within 3 minutes
  • 11:00:16Z / 11:00:27Z — two subagents 11 s apart, both seconds after being dispatched

The same api_error pattern (ConnectionRefused with isNetworkDown: true, request timeouts) appears in this machine's session logs on 2026-08-16/17/18 as well, so the network leg is flaky here — but the parent loop survives every one of these via its retry, while the subagent streaming path never does.

One more live datapoint: during the same window the permission-classifier call also surfaced "model is temporarily unavailable (timed out)" — so multiple independent request paths saw the same transient failures; only the subagent stream path turns them into a 600 s hang followed by a kill.

Expected behavior

The subagent streaming request should get the same treatment as the parent loop's requests: on a transient connection failure (refused / timeout / stream dead before first event), log an api_error and retry/reconnect with backoff instead of sitting silently until the 600 s watchdog fires and kills the agent. "Stream watchdog did not recover" appears to mean there is no recovery path at all for this case — the watchdog only detects, it cannot heal, and detection alone costs 10 minutes plus the kill.

Actual behavior

600 s of silence, then the subagent is killed mid-task.

Related

Mitigation that works today

Resuming the stalled subagent with a follow-up message (SendMessage) recovers it fully — the transcript survives, and in this session 15/15 resumed agents completed their tasks. That confirms nothing is lost except the 10 minutes and the manual resume; an automatic retry at the stream layer would remove the failure mode entirely.

Activity

  1. github-actions commented on Sep 22, 2026

    @github-actions

    Closing for now — inactive for too long. Please open a new issue if this is still relevant.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions