{"record":{"id":"0961e39abff68181","repo":"stablyai/orca","slug":"invalid-name-expected-a-finite-number-got-j","errorCode":null,"errorMessage":"Invalid ${name}: expected a finite number, got ${JSON.stringify(raw)}","messagePattern":"Invalid (.+?): expected a finite number, got (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/live-remote-bulk-open-freeze-metrics.mjs","lineNumber":16,"sourceCode":"/**\n * Pure metrics helpers for the live remote bulk-open freeze harness.\n * Kept separate so unit tests can drive the same code the repro uses.\n */\n\nexport const DEFAULT_SOFT_MS = 2000\nexport const DEFAULT_HARD_MS = 5000\n\nexport function readFreezeNumberEnv(name, fallback) {\n  const raw = process.env[name]\n  if (raw == null || raw.trim() === '') {\n    return fallback\n  }\n  const value = Number(raw)\n  if (!Number.isFinite(value)) {\n    throw new Error(`Invalid ${name}: expected a finite number, got ${JSON.stringify(raw)}`)\n  }\n  return value\n}\n\nexport function extractTerminalHandle(result) {\n  if (!result || typeof result !== 'object') {\n    return null\n  }\n  const candidates = [\n    result.handle,\n    result.terminalHandle,\n    result.agentTerminalHandle,\n    typeof result.terminal === 'string' ? result.terminal : result.terminal?.handle,\n    result.startupTerminal?.handle,\n    result.tab?.terminal,\n    result.tab?.handle\n  ]\n  for (const value of candidates) {","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/live-remote-bulk-open-freeze-metrics.mjs#L1-L34","documentation":"readFreezeNumberEnv reads a numeric configuration value (freeze soft/hard timeouts in ms) from a named process.env slot, falling back to a default when unset or blank. It throws when the raw string parses to a non-finite number — i.e. NaN or +/-Infinity — because a freeze timeout that is NaN/Infinity would silently disable or never trigger the freeze guard. Finite-number validation is the trust boundary for externally supplied timing.","triggerScenarios":"Setting the env var to a non-numeric string (e.g. ORCA_FREEZE_SOFT_MS=abc), to a hex/empty-ish value, or to the literal 'Infinity' (Number('Infinity') === Infinity, which fails Number.isFinite). The blank case is handled earlier and returns the fallback.","commonSituations":"Operator typos in CI env files, trailing whitespace is handled by trim but a stray unit like '2000ms' is not, or a templated value that resolves to an empty placeholder string after a deploy. The soft/hard defaults (2000/5000 ms) only apply when the var is entirely absent.","solutions":["Set the env var to a plain integer of milliseconds (e.g. ORCA_FREEZE_SOFT_MS=2000).","Strip any unit suffix or quotes in the provisioning script before exporting the var.","If the value is optional, leave it unset rather than assigning an empty/garbage string so the fallback kicks in cleanly."],"exampleFix":"# before\nexport ORCA_FREEZE_SOFT_MS=\"2000ms\"\n\n# after\nexport ORCA_FREEZE_SOFT_MS=2000","handlingStrategy":"validation","validationCode":"function readMs(name, fallback) {\n  const raw = process.env[name]\n  if (raw == null || raw.trim() === '') return fallback\n  const v = Number(raw)\n  if (!Number.isFinite(v) || v < 0) {\n    throw new Error(`${name}=${JSON.stringify(raw)} is not a finite non-negative number`)\n  }\n  return v\n}","typeGuard":"const isFiniteNumber = (v) => typeof v === 'number' && Number.isFinite(v)","tryCatchPattern":null,"preventionTips":["Document env vars as plain integer milliseconds with no units or quotes.","Validate env in a single config module at startup so failures surface early with the var name.","Use a config schema (zod/enquirer) for operator-supplied numeric env in CI."],"tags":["validation","env","configuration","number"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}