earendil-works/pi · error · ExecutionError
timeout
timeout
Error message
Invalid timeout: must be a finite number of seconds
What it means
Validation error from resolveTimeoutMs: the caller-supplied shell-exec timeout option is not a finite positive number of seconds (NaN, Infinity, zero, or negative). It is converted into an ExecutionError of kind 'timeout' before any child process is spawned, so an unusable timer never reaches setTimeout.
Solutions
- Pass a finite number of seconds as the timeout.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at packages/agent/src/harness/env/nodejs.ts:41 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
AI-assisted analysis of earendil-works/pi@4af9d21d3b (2026-08-24).
Data as JSON: /api/errors/53462af083fd666a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/harness/env/nodejs.ts:41
ExecutionError,
err,
FileError,
type FileInfo,
type FileKind,
ok,
type Result,
type ShellExecOptions,
toError,
} from "../types.ts";
const MAX_TIMEOUT_MS = 2_147_483_647;
const MAX_TIMEOUT_SECONDS = MAX_TIMEOUT_MS / 1000;
const EXIT_STDIO_GRACE_MS = 100;
function resolveTimeoutMs(timeout: number | undefined): Result<number | undefined, ExecutionError> {
if (timeout === undefined) return ok(undefined);
if (!Number.isFinite(timeout) || timeout <= 0) {
return err(new ExecutionError("timeout", "Invalid timeout: must be a finite number of seconds"));
}
const timeoutMs = timeout * 1000;
if (timeoutMs > MAX_TIMEOUT_MS) {
return err(new ExecutionError("timeout", `Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`));
}
return ok(timeoutMs);
}
function resolvePath(cwd: string, path: string): string {
let normalized = path;
if (normalized === "~") {
normalized = homedir();
} else if (normalized.startsWith("~/") || (process.platform === "win32" && normalized.startsWith("~\\"))) {
normalized = join(homedir(), normalized.slice(2));
} else if (normalized.startsWith("file://")) {
try {
normalized = fileURLToPath(normalized);View on GitHub (pinned to 4af9d21d3b)