can1357/oh-my-pi · error
${label} must be a finite number
Error message
${label} must be a finite number What it means
Thrown by numberValue(), which requires a JSON number that is finite (rejects NaN and ±Infinity). Fields like timeouts, ports, and PIDs in daemon specs, snapshots, operations, and RPC results go through it. It prevents non-numeric or non-finite values from entering daemon timing/logic code.
Source
Thrown at packages/coding-agent/src/launch/protocol.ts:182
}
function optionalString(value: unknown, label: string): string | undefined {
if (value === undefined) return undefined;
return stringValue(value, label);
}
function optionalRawString(value: unknown, label: string): string | undefined {
if (value === undefined) return undefined;
return rawString(value, label);
}
function booleanValue(value: unknown, label: string): boolean {
if (typeof value !== "boolean") throw new Error(`${label} must be a boolean`);
return value;
}
function numberValue(value: unknown, label: string): number {
if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${label} must be a finite number`);
return value;
}
function optionalNumber(value: unknown, label: string): number | undefined {
if (value === undefined) return undefined;
return numberValue(value, label);
}
function stringArray(value: unknown, label: string): string[] {
if (!Array.isArray(value)) throw new Error(`${label} must be an array of strings`);
const result: string[] = [];
for (const item of value) result.push(rawString(item, `${label} item`));
return result;
}
function stringRecord(value: unknown, label: string): Record<string, string> {
const source = record(value, label);
const result: Record<string, string> = {};View on GitHub (pinned to 9690622007)
Solutions
- Identify the field from the label and coerce to a finite number at the producer (Number(value), parseInt)
- Replace string numbers in config with unquoted numbers
- If the value can legitimately be absent, omit the key so optionalNumber is used
- Validate Infinity/NaN before serialization
Example fix
// before
parseDaemonSpec({ id: "d1", command: ["srv"], ready: { timeoutMs: "5000", log: "up" } })
// after
parseDaemonSpec({ id: "d1", command: ["srv"], ready: { timeoutMs: 5000, log: "up" } }) Defensive patterns
Strategy: validation
Validate before calling
function isFiniteNumber(v: unknown): v is number { return typeof v === "number" && Number.isFinite(v); }
if (!isFiniteNumber(payload.ready?.timeoutMs)) throw new Error("ready.timeoutMs must be a finite number"); Type guard
function isFiniteNumber(v: unknown): v is number { return typeof v === "number" && Number.isFinite(v); } Try / catch
try {
const snapshot = parseDaemonSnapshot(raw);
} catch (err) {
if (err instanceof Error && err.message.includes("must be a finite number")) {
// inspect the labeled field; coerce Number(value) and retry or fail fast
} else throw err;
} Prevention
- Never quote numeric values in config files
- Guard arithmetic that can produce NaN/Infinity before serialization
- Use optionalNumber-friendly omission (delete the key) instead of null for absent numbers
- Add JSON schema validation with type: number before handing off to the parser
When it happens
Trigger: Calling any daemon parse function with a field expected to be a number that is a string ("5000"), null, undefined, NaN, or Infinity — e.g. ready.timeoutMs, timeoutMs, pid, or port fields.
Common situations: Config authored with quoted numbers; JSON.stringify of Infinity/NaN producing null; division or arithmetic upstream producing NaN; missing optional field serialized as null instead of omitted.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ${label} must be a string
- ${label} must be a boolean
- ${label} must be an array of strings
- vault:// path resolution only supports plain filesystem path
- send requires data or signal
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d997ccfaded7f0fe.
Report an issue: GitHub.