Skip to content

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

@yanmo96

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions