{"record":{"id":"d80396f91f658533","repo":"koala73/worldmonitor","slug":"deadlinems-must-be-a-positive-number","errorCode":null,"errorMessage":"deadlineMs must be a positive number","messagePattern":"deadlineMs must be a positive number","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/mcp-smoke-http.mjs","lineNumber":76,"sourceCode":"      if (record.errors.length === MAX_ERROR_ENTRIES) break;\n    }\n  }\n  return record;\n}\n\nexport function formatSafeError(error) {\n  const safe = serializeSafeError(error);\n  const parts = [safe.name, safe.code, safe.message].filter(Boolean);\n  return parts.join(': ') || 'Unknown error';\n}\n\nexport function createTimedFetch({\n  deadlineMs,\n  fetchImpl = globalThis.fetch,\n  onRecord = () => {},\n  userAgent,\n} = {}) {\n  if (!(Number.isFinite(deadlineMs) && deadlineMs > 0)) throw new Error('deadlineMs must be a positive number');\n  let sequence = 0;\n\n  return async function timedFetch(url, init = {}, context = {}) {\n    const startedAt = Date.now();\n    const rpcMethod = boundedRpcMethod(context.rpcMethod);\n    const record = {\n      sequence: ++sequence,\n      group: boundedText(context.group || 'unclassified'),\n      hostname: null,\n      pathname: null,\n      method: String(init.method || 'GET').toUpperCase(),\n      ...(rpcMethod ? { rpcMethod } : {}),\n      elapsedMs: 0,\n      deadlineMs,\n      stage: 'parse',\n      status: null,\n      outcome: 'transport_error',\n      responseHeaders: {},","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/koala73/worldmonitor/blob/e586b8b4b80f595aa7ece295eec10d76f2921240/scripts/mcp-smoke-http.mjs#L58-L94","documentation":"createTimedFetch() builds a fetch wrapper bounded by a deadline. It validates deadlineMs up front: if it is not a finite number greater than 0, it throws 'deadlineMs must be a positive number'. This is a fail-fast guard so misconfiguration surfaces at construction time rather than producing requests with a broken deadline.","triggerScenarios":"Calling createTimedFetch() with no options (deadlineMs undefined), deadlineMs: null, deadlineMs: 0, a negative value, or a non-numeric string.","commonSituations":"Reading the budget from an unset env var (undefined after Number() coercion is NaN), refactored call sites dropping the option, or passing a string from CLI parsing without Number() conversion.","solutions":["Pass a positive finite deadlineMs, e.g. createTimedFetch({ deadlineMs: 60000 })","Coerce string inputs with Number() before passing, then validate","Check the call site for a missing or renamed deadlineMs option"],"exampleFix":"// before\nconst timedFetch = createTimedFetch({ userAgent: UA }); // deadlineMs undefined\n// after\nconst timedFetch = createTimedFetch({ deadlineMs: 60000, userAgent: UA });","handlingStrategy":"validation","validationCode":"const budgetMs = Number(process.env.BUDGET_MS ?? 60000);\nif (!(Number.isFinite(budgetMs) && budgetMs > 0)) throw new Error('BUDGET_MS must be a positive number');\nconst timedFetch = createTimedFetch({ deadlineMs: budgetMs });","typeGuard":"const isValidDeadline = (v) => typeof v === 'number' && Number.isFinite(v) && v > 0;","tryCatchPattern":"try {\n  const timedFetch = createTimedFetch({ deadlineMs: parsedDeadline });\n} catch (err) {\n  if (err.message.startsWith('deadlineMs')) console.error('Pass a positive finite deadlineMs in milliseconds');\n  throw err;\n}","preventionTips":["Always pass deadlineMs explicitly as a positive number","Coerce and validate string inputs with Number() before constructing","Fail fast in config-loading code so bad values never reach createTimedFetch"],"tags":["timeout","http","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"e586b8b4b80f595aa7ece295eec10d76f2921240","analyzedAt":"2026-09-22T01:50:49.965Z","contentChangedAt":"2026-09-22T01:50:49.965Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}