From 6ba02c9d0adc2cfb002d20f251b66b9e618869f4 Mon Sep 17 00:00:00 2001 From: Jesse Merhi <79823012+jesse-merhi@users.noreply.github.com> Date: Sat, 15 Aug 2026 14:20:12 +1000 Subject: [PATCH] fix(scripts): saturate the tsgo watchdog at Node's timer ceiling An OPENCLAW_TSGO_TIMEOUT_MS above 2147483647 reached setTimeout unchanged, where Node collapses it to a 1ms delay, so raising the override killed healthy typechecks immediately instead of loosening the bound. Co-Authored-By: Claude Opus 5 (1M context) --- scripts/run-tsgo.mts | 7 ++++++- test/scripts/run-tsgo.test.ts | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/scripts/run-tsgo.mts b/scripts/run-tsgo.mts index 22ff48c29af1..3ea27918e097 100644 --- a/scripts/run-tsgo.mts +++ b/scripts/run-tsgo.mts @@ -18,6 +18,8 @@ import { /** Watchdog bound for one tsgo run; sized well above a healthy whole-program check. */ const DEFAULT_TSGO_TIMEOUT_MS = 45 * 60 * 1000; +/** Node's timer ceiling: a longer delay silently becomes 1ms, so a raised override must saturate. */ +const MAX_TSGO_TIMEOUT_MS = 2_147_483_647; async function main(): Promise { const hostResources = { @@ -49,7 +51,10 @@ async function main(): Promise { } ensureRepoToolNodeModulesLink(tsgoPath); - const timeoutMs = readPositiveEnvInt("OPENCLAW_TSGO_TIMEOUT_MS", env, DEFAULT_TSGO_TIMEOUT_MS); + const timeoutMs = Math.min( + readPositiveEnvInt("OPENCLAW_TSGO_TIMEOUT_MS", env, DEFAULT_TSGO_TIMEOUT_MS), + MAX_TSGO_TIMEOUT_MS, + ); try { // Managed run owns the whole tsgo process tree: on timeout it SIGKILLs the // process group, because a wedged checker ignores SIGTERM and would otherwise diff --git a/test/scripts/run-tsgo.test.ts b/test/scripts/run-tsgo.test.ts index 15aae286f7c5..2e819fa294a4 100644 --- a/test/scripts/run-tsgo.test.ts +++ b/test/scripts/run-tsgo.test.ts @@ -283,4 +283,14 @@ describe.skipIf(process.platform === "win32")("run-tsgo watchdog", () => { expect(result.status).toBe(0); expect(result.stderr).not.toContain("killed the tsgo process tree"); }, 30_000); + + it("saturates an override past Node's timer ceiling instead of arming a 1ms watchdog", () => { + const cwd = createTempDir("openclaw-run-tsgo-watchdog-"); + writeFakeTsgo(cwd, "#!/bin/sh\nsleep 1\nexit 0\n"); + + const result = runFakeTsgo(cwd, "2147483648"); + + expect(result.status).toBe(0); + expect(result.stderr).not.toContain("killed the tsgo process tree"); + }, 30_000); });