diff --git a/src/tui/local-run-shutdown.ts b/src/tui/local-run-shutdown.ts index b4b975f23272..5bec3ad3ed2a 100644 --- a/src/tui/local-run-shutdown.ts +++ b/src/tui/local-run-shutdown.ts @@ -1,5 +1,8 @@ // Coordinates graceful shutdown for local TUI runs. -import { parseStrictNonNegativeInteger } from "../infra/parse-finite-number.js"; +import { + MAX_TIMER_TIMEOUT_MS, + parseStrictNonNegativeInteger, +} from "../infra/parse-finite-number.js"; // Local TUI runs get extra shutdown time because embedded agents/providers may still be closing. const LOCAL_RUN_SHUTDOWN_GRACE_MS = 120_000; @@ -9,7 +12,7 @@ export function resolveLocalRunShutdownGraceMs(): number { const raw = process.env.OPENCLAW_TUI_LOCAL_RUN_SHUTDOWN_GRACE_MS?.trim(); const parsed = parseStrictNonNegativeInteger(raw); if (parsed !== undefined) { - return parsed; + return Math.min(parsed, MAX_TIMER_TIMEOUT_MS); } return LOCAL_RUN_SHUTDOWN_GRACE_MS; } diff --git a/src/tui/tui.test.ts b/src/tui/tui.test.ts index a05a67f06f62..1f90313499df 100644 --- a/src/tui/tui.test.ts +++ b/src/tui/tui.test.ts @@ -2,6 +2,7 @@ import { EventEmitter } from "node:events"; import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; +import { MAX_TIMER_TIMEOUT_MS } from "../infra/parse-finite-number.js"; import { MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "../shared/assistant-error-format.js"; import { withEnv } from "../test-utils/env.js"; import { getSlashCommands, parseCommand } from "./commands.js"; @@ -237,6 +238,14 @@ describe("resolveTuiShutdownHardExitMs", () => { expect(resolveTuiShutdownHardExitMs({ localMode: true })).toBe(122000); }); }); + + it("clamps oversized local run shutdown grace values", () => { + withEnv({ OPENCLAW_TUI_LOCAL_RUN_SHUTDOWN_GRACE_MS: String(Number.MAX_SAFE_INTEGER) }, () => { + expect(resolveTuiShutdownHardExitMs({ localMode: true })).toBe( + MAX_TIMER_TIMEOUT_MS + 2000, + ); + }); + }); }); describe("resolveTuiSessionKey", () => {