Skip to content

fix: Reset subagent session idle timeout on successful tool calls to prevent premature termination #94124

Description

@kumaxs

Problem

When a subagent (sessions_spawn with mode: "run") performs tool calls (e.g., web_fetch, read, exec) that take time, the LLM is idle during those calls. If no LLM response happens for 120 seconds, the subagent session is terminated with:

LLM idle timeout (120s): no response from model

This kills research/analysis subagents that are mid-data-collection — they may have gathered all the data and be about to output the final report, but the 120s window expires and the session is killed.

Root Cause

The 120s idle timeout is a hardcoded kernel-level protection (SessionWriteLockTimeoutError / EmbeddedAttemptSessionTakeoverError). The embedded agent runner releases the prompt lock while waiting for tools. If no new LLM turn happens within 120 seconds, another attempt can take over the session and the original one is killed.

agents.defaults.subagents.runTimeoutSeconds (default 900s / 15min) only controls total wall-clock time, not idle time between LLM turns — so a subagent can be well within its total budget but still get killed because no LLM output happened for 2 minutes during tool calls.

Proposed Fix

Not adding a configurable parameter. Instead, make the session timeout smarter:

Instead of a fixed 120s idle timer, add a tool heartbeat mechanism:

  1. Each time a tool call returns successfully, reset a 30-second counter for the session idle timeout
  2. If the 30-second counter expires without any LLM output AND no tool activity, then the session times out (as it should)
  3. If tools are actively returning results, the session stays alive regardless of LLM idle time

This way:

  • Research-heavy subagents that spend minutes collecting data survive
  • Truly stalled subagents (no LLM, no tools) still time out
  • The fix is purely in the embedded agent runner — no config schema changes needed

Implementation Sketch

In the embedded agent runner (dist/run-embedded-agent-*.js or similar):

  • When a tool call result is written back to the session, refresh the idle heartbeat timestamp
  • The existing 120s check should compare against this last-activity timestamp instead of last-LLM-response timestamp

No new config fields. No breaking changes. Just a smarter timeout origin.

Metadata

Metadata

Assignees

Labels

P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivity

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions