openclaw/src/utils
hcl fd74fc5a4f
fix(heartbeat): clamp scheduler delay to Node setTimeout cap (#71414) (#71478)
* fix(heartbeat): clamp scheduler delay to Node setTimeout cap (#71414)

When `agents.defaults.heartbeat.every` resolves to >2_147_483_647 ms
(~24.85d), the previous scheduleNext() called setTimeout with the raw
delay. Node clamps any delay > 2^31-1 to 1 ms, fires the callback, and
the heartbeat re-arms with the same oversized value - a tight loop that
floods the log with TimeoutOverflowWarning and crashes the gateway with
exit code 1.

Clamp the computed delay to HEARTBEAT_MAX_TIMEOUT_MS (2_147_483_647)
before calling setTimeout. The worst case is now one heartbeat every
~24.85d instead of crash-loop. Warn once per process when clamping
fires, so a misconfigured "365d" remains visible without flooding.

This is a defense-in-depth fix at the scheduler layer; loadConfig-level
rejection is a broader change with more blast radius and a separate
question (some users may legitimately want "every: 365d" to mean
"effectively never"). The clamped behaviour is closer to that intent
than the crash is.

Test: new scheduler test sets heartbeat.every="365d" with fake timers,
advances 60s, and asserts runSpy was never called (with the bug, it
would be called ~60_000 times).

* style: format heartbeat scheduler clamp

* fix: share safe timeout delay clamp (#71478) (thanks @hclsys)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-04-25 10:03:43 +01:00
..
account-id.ts
boolean.ts
chunk-items.ts
cjk-chars.test.ts
cjk-chars.ts
delivery-context.shared.ts perf(channels): split hot-path message channel normalization 2026-04-13 18:22:12 +01:00
delivery-context.test.ts refactor: enforce plugin-owned channel boundaries 2026-04-18 22:48:27 +01:00
delivery-context.ts refactor: share conversation target normalization 2026-04-19 05:02:03 +01:00
delivery-context.types.ts
directive-tags.test.ts
directive-tags.ts fix(pair): render /pair qr as media (#70047) 2026-04-22 03:31:09 -05:00
fetch-timeout.ts
mask-api-key.test.ts
mask-api-key.ts
message-channel-constants.ts
message-channel-core.ts perf(channels): split hot-path message channel normalization 2026-04-13 18:22:12 +01:00
message-channel-normalize.ts perf(channels): split hot-path message channel normalization 2026-04-13 18:22:12 +01:00
message-channel.test.ts
message-channel.ts
normalize-secret-input.test.ts
normalize-secret-input.ts
parse-json-compat.ts
provider-utils.test.ts
provider-utils.ts
queue-helpers.test.ts
queue-helpers.ts
reaction-level.test.ts
reaction-level.ts
run-with-concurrency.test.ts
run-with-concurrency.ts
safe-json.ts
shell-argv.ts
timer-delay.test.ts fix(heartbeat): clamp scheduler delay to Node setTimeout cap (#71414) (#71478) 2026-04-25 10:03:43 +01:00
timer-delay.ts fix(heartbeat): clamp scheduler delay to Node setTimeout cap (#71414) (#71478) 2026-04-25 10:03:43 +01:00
transcript-tools.test.ts
transcript-tools.ts
usage-format.test.ts fix: correct tiered model pricing costs 2026-04-21 03:48:25 +01:00
usage-format.ts chore: apply core lint cleanups 2026-04-23 05:30:49 +01:00
utils-misc.test.ts
with-timeout.ts
zod-parse.ts