Skip to content

cron run: default 30s timeout kills long-running jobs even when job itself is healthy #54320

Description

@yanmo96

Problem

openclaw cron run <id> has a hardcoded default timeout of 30,000ms (30 seconds) in the CLI. There is no config flag to override this default.

Impact: Manually triggering long-running cron jobs via the CLI times out at 30s even when:

  • The job has payload.timeoutSeconds set correctly (e.g. 900s)
  • The isolated session is healthy and completes successfully in ~90-100s
  • The scheduled (non-manual) execution works correctly

This creates a false ERROR state: the cron framework records status: error with error: "cron: job execution timed out" even though the isolated session actually completed successfully.

Evidence

A multi-step weekly backtest job was used as a test case:

  • Manual trigger (first attempt): openclaw cron run <id> - killed at exactly 30,014ms, status ERROR
  • Manual trigger (second attempt): openclaw cron run <id> --timeout 0 - ran for 98,359ms (~98s), status OK
  • Scheduled (Sunday 6pm): No timeout issue - isolated session completes naturally in ~98s every time

Root Cause

The 30s default is hardcoded in the CLI entry point (cron-run.js):

--timeout <ms>   Timeout in ms (default: "30000")

There is no corresponding config flag (cron.runTimeoutMs, cron.defaultTimeout, etc.) to change this default. Users must manually pass --timeout 0 every time.

Impact Summary

Trigger method Timeout behavior Works around
Scheduled (gateway-triggered) No CLI cap - waits for session Fine
Manual cron run <id> Hard 30s CLI cap Use --timeout 0
sessions_spawn (subagents) agents.defaults.subagents.runTimeoutSeconds (default 0 = no timeout) Fine

Only the cron run CLI command is affected.

Proposed Fix

Option A (simplest): Change the default to --timeout 0 (no timeout) in the CLI:

--timeout <ms>   Timeout in ms (default: "0", i.e. no limit)

Manual runs would now wait indefinitely, matching scheduled run behavior.

Option B (safer): Add a config flag cron.runTimeoutMs:

{
  cron: {
    runTimeoutMs: 0,  // default 30000ms for backward compat; 0 = no timeout
  }
}

Option C (most explicit): Require users to always pass --timeout for cron run, removing the default entirely.

Workaround (current)

openclaw cron run <id> --timeout 0

A shell alias mitigates it:

alias cronrun="openclaw cron run --timeout 0"

Metadata

  • OpenClaw version: 2026.3.23-2
  • Related: agents.defaults.subagents.runTimeoutSeconds (already supports 0 = no timeout for subagents, but cron run is a separate code path)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions