openclaw - ✅(Solved) Fix BUG: Subagent runTimeoutSeconds default fallback resolves to infinite timeout instead of configured default [7 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#54936Fetched 2026-04-08 01:34:20
View on GitHub
Comments
0
Participants
1
Timeline
19
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×9referenced ×8labeled ×2

When spawning a subagent via sessions_spawn without passing an explicit runTimeoutSeconds, the timeout resolves to 0, which the timeout resolver interprets as "no timeout" (infinite). The configured default at agents.defaults.subagents.runTimeoutSeconds is never applied. Subagent runs have no effective timeout unless the caller explicitly passes one.

Root Cause

Subagent runs indefinitely. The configured default is never applied because the fallback chain resolves to 0, and the timeout resolver treats 0 as "disable timeout."

Fix Action

Fix / Workaround

Workaround: Explicitly pass runTimeoutSeconds in every sessions_spawn call.

PR fix notes

PR #54968: fix: use configured default when subagent runTimeoutSeconds is omitted

Description (problem / solution / changelog)

Summary

When spawning a subagent without an explicit runTimeoutSeconds, the fallback chain resolved to 0, which the timeout resolver interprets as "disable timeout" (infinite). The configured default at agents.defaults.subagents.runTimeoutSeconds was never applied.

Changes

  • Remove ?? 0 fallback in resolveSubagentWaitTimeoutMs() so undefined flows through to resolveAgentTimeoutMs(), which correctly falls back to the configured default.
  • Also remove ?? 0 in the two call sites that pass runTimeoutSeconds to this function, ensuring undefined propagates correctly.

Testing

  • Existing test suite passes
  • The resolver now correctly uses agents.defaults.subagents.runTimeoutSeconds when no explicit timeout is provided

Fixes openclaw/openclaw#54936

Changed files

  • src/agents/subagent-registry.ts (modified, +3/-3)

PR #54999: fix: honor default subagent run timeout

Description (problem / solution / changelog)

Summary\n- preserve omitted runTimeoutSeconds so sessions_spawn can inherit the configured default timeout\n- avoid coercing missing timeouts to 0 when registering or replacing subagent runs\n- add registry regression coverage for omitted timeout propagation and steer restarts\n\n## Testing\n- pnpm test -- --run src/agents/openclaw-tools.subagents.sessions-spawn-default-timeout.test.ts src/agents/subagent-registry.test.ts\n\nFixes #54936

Changed files

  • src/agents/subagent-registry.test.ts (modified, +56/-0)
  • src/agents/subagent-registry.ts (modified, +3/-3)

PR #55020: fix: let subagent runTimeoutSeconds fall through to configured default

Description (problem / solution / changelog)

Fixes #54936

When no explicit runTimeoutSeconds is passed, the fallback was 0 which the timeout resolver treats as "disable timeout". Changed to undefined so the resolver falls through to the configured agents.defaults.subagents.runTimeoutSeconds.

Changed files

  • src/agents/subagent-registry.ts (modified, +1/-1)

PR #55038: fix(subagent): resolve subagent-specific runTimeoutSeconds from config

Description (problem / solution / changelog)

Summary

Fixes #54936 - Subagent runTimeoutSeconds default fallback resolves to infinite timeout instead of configured default

When spawning a subagent via sessions_spawn without passing an explicit runTimeoutSeconds, the timeout resolved to 0, which was interpreted as "no timeout" (infinite). The configured default at agents.defaults.subagents.runTimeoutSeconds was never applied.

Changes

  • src/agents/timeout.ts: Add forSubagent option to resolveAgentTimeoutSeconds and resolveAgentTimeoutMs to check agents.defaults.subagents.runTimeoutSeconds first before falling back to main agent timeout
  • src/agents/subagent-spawn.ts: Change fallback from 0 to undefined so the timeout resolver uses config defaults
  • src/agents/subagent-registry.ts: Pass forSubagent: true to timeout resolution and change fallbacks to undefined
  • src/agents/subagent-depth.test.ts: Add tests for subagent-specific timeout resolution

Root Cause

The fallback chain resolved to 0 when no explicit timeout was passed:

params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0

Then in resolveAgentTimeoutMs, overrideSeconds: 0 was treated as "disable timeout" instead of "use config default".

Testing

Added unit tests to verify:

  • Subagent-specific config is used when forSubagent: true
  • Falls back to main agent timeout when subagent config is not set
  • Explicit 0 still disables timeout as intended
  • Undefined uses the configured default

All existing tests pass.

Impact

  • Subagents spawned without explicit runTimeoutSeconds will now respect agents.defaults.subagents.runTimeoutSeconds
  • Users who explicitly set runTimeoutSeconds: 0 will still get no timeout (as intended)
  • Backward compatible - explicit timeouts work as before

Changed files

  • src/agents/subagent-depth.test.ts (modified, +26/-0)
  • src/agents/subagent-registry.ts (modified, +3/-3)
  • src/agents/subagent-spawn.ts (modified, +2/-3)
  • src/agents/timeout.ts (modified, +23/-8)
  • src/gateway/server-methods/chat.ts (modified, +4/-0)

PR #55115: fix: subagent runTimeoutSeconds default fallback resolves to infinite timeout

Description (problem / solution / changelog)

Fixes #54936

Root Cause

Three call sites in subagent-registry.ts use ?? 0 as the final fallback for runTimeoutSeconds. resolveAgentTimeoutMs treats overrideSeconds === 0 as NO_TIMEOUT (infinite). Because the fallback always provides 0, the configured agents.defaults.subagents.runTimeoutSeconds is never applied.

Fix

Change all three fallbacks from ?? 0 to ?? undefined:

// Before
const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;
return resolveAgentTimeoutMs({ cfg, overrideSeconds: runTimeoutSeconds ?? 0 });

// After
const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? undefined;
return resolveAgentTimeoutMs({ cfg, overrideSeconds: runTimeoutSeconds });

With overrideSeconds = undefined, the resolver skips the override branch and returns defaultMs (the configured default). An explicit runTimeoutSeconds: 0 from the caller still disables the timeout.

Changed files

  • src/agents/subagent-registry-run-manager.ts (modified, +2/-2)
  • src/agents/subagent-registry.ts (modified, +1/-1)

PR #202: 🦅 Scout: Critical Inherited Defect Report - 2026-03-24

Description (problem / solution / changelog)

🦅 Scout: Critical Inherited Defect Report - 2026-03-24

Scanned the upstream OpenClaw repository and identified 3 defect patterns representing critical/high-impact regressions introduced in the recent v2026.3.24 release that are present in our local codebase:

Upstream Issue #54931: BUG: Discord health-monitor triggers uncaught exception crash loop

  • Location in our code: src/discord/monitor/provider.lifecycle.ts
  • Observed Behavior: The Discord health-monitor handles aborts by setting gateway.options.reconnect = { maxAttempts: 0 } and calling gateway.disconnect(). When the WebSocket close handler immediately fires, it checks reconnectAttempts(0) >= maxAttempts(0), evaluating to true, which emits a new Error that goes uncaught, crashing the entire Node.js process and disrupting all subagent sessions.
  • Expected Behavior: Health-monitor should gracefully restart the Discord channel without crashing the gateway process. The forced disconnection path shouldn't invoke the unexpected connection-retry limits error logic, or if it does, the error should be correctly caught instead of bringing down the gateway process.
  • Impact Severity: High — Gateway crashes periodically (every ~35 mins) if Discord goes stale. All running subagent sessions are disrupted or killed.

Upstream Issue #54936: BUG: Subagent runTimeoutSeconds default fallback resolves to infinite timeout instead of configured default

  • Location in our code: src/agents/subagent-registry.ts
  • Observed Behavior: When a subagent is spawned via sessions_spawn without explicitly passing a runTimeoutSeconds parameter, the parameter initializer mistakenly falls back to 0. The downstream timeout resolver interprets 0 as an explicit "disable timeout" instruction, causing the subagent to run indefinitely rather than falling back to the configured default (agents.defaults.subagents.runTimeoutSeconds).
  • Expected Behavior: Subagents should be killed after the configured default runtime timeout when no explicit timeout is passed during the spawn call.
  • Impact Severity: Medium — Subagents spawned without explicit timeouts will run indefinitely, potentially creating zombie processes that stall and exhaust system resources.

Upstream Issue #54975: BUG: All tools with required parameters receive empty {} arguments - Gateway parameter parsing failure

  • Location in our code: Provider integrations (Anthropic/OpenAI compat)
  • Observed Behavior: Third-party providers fail to correctly serialize/send tool parameters, causing validation failures where the agent's intent is lost. Tools receive empty {} arguments instead of the correctly passed parameters.
  • Expected Behavior: Tools should receive the correctly passed parameters and execute successfully.
  • Impact Severity: High — Complete automation blockage when using specific models.

The .jules/scout.md journal has been updated with these patterns for future tracking.


PR created automatically by Jules for task 2111446781902950035 started by @MillionthOdin16

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

Summary by CodeRabbit

  • Documentation
    • Added documentation for known defect patterns and tracked issues.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Changed files

  • .jules/scout.md (added, +14/-0)
  • report.txt (added, +13/-0)

PR #61870: fix: subagent runTimeoutSeconds default fallback resolves to infinite timeout

Description (problem / solution / changelog)

Fixes #54936

Root Cause

Three call sites use ?? 0 as the final fallback for runTimeoutSeconds. resolveAgentTimeoutMs treats overrideSeconds === 0 as NO_TIMEOUT (infinite).

Fix

Remove the redundant ?? 0 fallbacks and restore ?? 0 only in resolveSubagentWaitTimeoutMs where it maps to NO_TIMEOUT_MS via the existing resolveAgentTimeoutMs path.

Changed files

  • src/agents/subagent-registry-run-manager.ts (modified, +2/-2)
  • src/agents/subagent-registry.ts (modified, +1/-1)

Code Example

Tested with runTimeoutSeconds: 600 (10 min) configured. Spawned subagent without explicit timeout. Subagent ran 15+ minutes before being manually killed.

Root cause — three-step resolution chain:

Step 1Spawn registration (pi-embedded-BaSvmUpW.js:98937):

const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;

When not passed, resolves to 0.

Step 2Wait timeout resolution (pi-embedded-BaSvmUpW.js:98613-98617):

function resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds) {
    return resolveAgentTimeoutMs({
        cfg,
        overrideSeconds: runTimeoutSeconds ?? 0
    });
}

Passes overrideSeconds: 0.

Step 3Timeout resolver (manager-BFi-xqLj.js:18-37):

const overrideSeconds = normalizeNumber(opts.overrideSeconds);
if (overrideSeconds !== void 0) {
    if (overrideSeconds === 0) return NO_TIMEOUT_MS;  // ← treats 0 as "disable"
    if (overrideSeconds < 0) return defaultMs;
    return clampTimeoutMs(overrideSeconds * 1e3);
}
return defaultMs;  // ← configured default, never reached

The resolver correctly uses the configured default when overrideSeconds is undefined, but Step 1 always provides 0 as fallback — so undefined never reaches the resolver.
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Summary

When spawning a subagent via sessions_spawn without passing an explicit runTimeoutSeconds, the timeout resolves to 0, which the timeout resolver interprets as "no timeout" (infinite). The configured default at agents.defaults.subagents.runTimeoutSeconds is never applied. Subagent runs have no effective timeout unless the caller explicitly passes one.

Steps to reproduce

  1. Set agents.defaults.subagents.runTimeoutSeconds: 600 (10 min) in config
  2. Spawn a subagent: sessions_spawn({ agentId: "my-agent", task: "..." }) — without passing runTimeoutSeconds
  3. Observe: the subagent runs indefinitely past 10 minutes — never killed by timeout
  4. Expected: subagent should be killed after 600 seconds (10 min)

Expected behavior

Subagent should be killed after the configured agents.defaults.subagents.runTimeoutSeconds when no explicit timeout is passed in the spawn call.

Actual behavior

Subagent runs indefinitely. The configured default is never applied because the fallback chain resolves to 0, and the timeout resolver treats 0 as "disable timeout."

OpenClaw version

2026.3.24

Operating system

Ubuntu 24.04 LTS (Linux 6.18.7 x64)

Install method

npm global

Model

anthropic/claude-sonnet-4-6

Provider / routing chain

openclaw -> anthropic (direct)

Additional provider/model setup details

Bug is in subagent timeout resolution, not model-specific.

Logs, screenshots, and evidence

Tested with runTimeoutSeconds: 600 (10 min) configured. Spawned subagent without explicit timeout. Subagent ran 15+ minutes before being manually killed.

Root cause — three-step resolution chain:

Step 1 — Spawn registration (pi-embedded-BaSvmUpW.js:98937):

const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;

When not passed, resolves to 0.

Step 2 — Wait timeout resolution (pi-embedded-BaSvmUpW.js:98613-98617):

function resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds) {
    return resolveAgentTimeoutMs({
        cfg,
        overrideSeconds: runTimeoutSeconds ?? 0
    });
}

Passes overrideSeconds: 0.

Step 3 — Timeout resolver (manager-BFi-xqLj.js:18-37):

const overrideSeconds = normalizeNumber(opts.overrideSeconds);
if (overrideSeconds !== void 0) {
    if (overrideSeconds === 0) return NO_TIMEOUT_MS;  // ← treats 0 as "disable"
    if (overrideSeconds < 0) return defaultMs;
    return clampTimeoutMs(overrideSeconds * 1e3);
}
return defaultMs;  // ← configured default, never reached

The resolver correctly uses the configured default when overrideSeconds is undefined, but Step 1 always provides 0 as fallback — so undefined never reaches the resolver.

Impact and severity

Medium — All subagent runs spawned without explicit runTimeoutSeconds have no timeout. Stalled/zombie subagents consume resources indefinitely until manually killed. The configured agents.defaults.subagents.runTimeoutSeconds setting has no effect on spawn-based subagents.

Additional information

Suggested fix — change the fallback in Step 1 from 0 to undefined:

// Before: const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;

// After: const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? undefined;

This way overrideSeconds reaches the resolver as undefined, correctly falling through to resolveAgentTimeoutSeconds(cfg) (the configured default). An explicit runTimeoutSeconds: 0 from the caller would still disable the timeout as intended.

Workaround: Explicitly pass runTimeoutSeconds in every sessions_spawn call.

extent analysis

Fix Plan

To fix the issue, we need to modify the fallback value in the runTimeoutSeconds resolution chain.

  • Change the line in pi-embedded-BaSvmUpW.js (around line 98937) from:
const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;

to:

const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds;

Alternatively, you can also use undefined as the fallback value:

const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? undefined;

This change allows the overrideSeconds to reach the resolver as undefined, correctly falling through to the configured default.

Verification

To verify the fix, follow these steps:

  • Set agents.defaults.subagents.runTimeoutSeconds to a non-zero value (e.g., 600) in your config.
  • Spawn a subagent using sessions_spawn without passing an explicit runTimeoutSeconds.
  • Observe that the subagent is killed after the configured timeout period (e.g., 10 minutes).
  • Test with an explicit runTimeoutSeconds: 0 to ensure that the timeout is still disabled as intended.

Extra Tips

  • Make sure to update the pi-embedded-BaSvmUpW.js file with the correct changes.
  • If you're using a version control system, create a new branch for the fix and test it thoroughly before merging it into the main branch.
  • Consider adding automated tests to ensure that the fix works as expected and to prevent similar issues in the future.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Subagent should be killed after the configured agents.defaults.subagents.runTimeoutSeconds when no explicit timeout is passed in the spawn call.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING