Skip to content

Heartbeat duration every >24.85d overflows Node setTimeout, crashes gateway with no auto-respawn #71414

@mayank6136

Description

@mayank6136

Summary

Setting agents.defaults.heartbeat.every to a duration greater than ~24.85 days (Node.js's signed-32-bit setTimeout cap of 2,147,483,647 ms) causes the heartbeat scheduler to fire in a tight loop and eventually crashes the gateway with OpenClaw exited with code 1. The container wrapper does not auto-respawn the gateway after exit. The CLI silently falls back to embedded mode on the next invocation.

Reproduction

  1. In openclaw.json, set:
    { "agents": { "defaults": { "heartbeat": { "every": "365d" } } } }
    (or any value that resolves to >2,147,483,647 ms — i.e. anything beyond ~24d 20h)
  2. Restart the gateway and watch container logs.

Observed behaviour

Container logs flood with thousands of lines like:

(node:41) TimeoutOverflowWarning: 23111245866 does not fit into a 32-bit signed integer.
Timeout duration was set to 1.

Eventually the gateway exits:

[22:29:40] WARN: OpenClaw exited with code 1

After this, port 18789 is not listening; subsequent openclaw agent invocations silently fall back to embedded mode (see related issue on silent embedded fallback). docker exec ... ps -ef shows no gateway process; only the proxy node server.mjs remains.

Root cause

Per Node.js docs, setTimeout(fn, delay) clamps delay > 2147483647 to 1 ms. The heartbeat scheduler appears to compute "next fire = now + every" and pass it directly to setTimeout, so the very-large delay gets truncated to 1 ms. The function then runs immediately, recomputes, and re-arms — a tight loop that ultimately exhausts something (event loop / promise queue / heap) and the process dies.

Expected behaviour

At least one of:

  • Reject the config with a clear error during loadConfig if the resolved ms exceeds Node's setTimeout limit.
  • Clamp internally to 2^31-1 ms with a warning.
  • Use a recursive long-timer pattern (re-arm every 24d until the cumulative target is reached).

Additionally, the wrapper / supervisor should auto-respawn the gateway after exit code 1 instead of leaving the proxy alive but the gateway dead.

Workaround

Use a value safely under the cap: "every": "24d" (≈ 2,073,600,000 ms) is safe and still effectively "never" for a "durably disabled" heartbeat.

Environment

OpenClaw 2026.4.12 (1c0672b), running in container ghcr.io/hostinger/hvps-openclaw:latest on Linux/Docker.

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