koala73/worldmonitor · error

deadlineMs must be a positive number

Error message

deadlineMs must be a positive number

What it means

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.

Solutions

  1. Pass a positive finite deadlineMs, e.g. createTimedFetch({ deadlineMs: 60000 })
  2. Coerce string inputs with Number() before passing, then validate
  3. Check the call site for a missing or renamed deadlineMs option

Example fix

// before
const timedFetch = createTimedFetch({ userAgent: UA }); // deadlineMs undefined
// after
const timedFetch = createTimedFetch({ deadlineMs: 60000, userAgent: UA });
Defensive patterns

Strategy: validation

Validate before calling

const budgetMs = Number(process.env.BUDGET_MS ?? 60000);
if (!(Number.isFinite(budgetMs) && budgetMs > 0)) throw new Error('BUDGET_MS must be a positive number');
const timedFetch = createTimedFetch({ deadlineMs: budgetMs });

Type guard

const isValidDeadline = (v) => typeof v === 'number' && Number.isFinite(v) && v > 0;

Try / catch

try {
  const timedFetch = createTimedFetch({ deadlineMs: parsedDeadline });
} catch (err) {
  if (err.message.startsWith('deadlineMs')) console.error('Pass a positive finite deadlineMs in milliseconds');
  throw err;
}

Prevention

When it happens

Trigger: Calling createTimedFetch() with no options (deadlineMs undefined), deadlineMs: null, deadlineMs: 0, a negative value, or a non-numeric string.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@e586b8b4b8 (2026-09-22). Data as JSON: /api/errors/d80396f91f658533. Report an issue: GitHub.

Appendix: source

Thrown at scripts/mcp-smoke-http.mjs:76

      if (record.errors.length === MAX_ERROR_ENTRIES) break;
    }
  }
  return record;
}

export function formatSafeError(error) {
  const safe = serializeSafeError(error);
  const parts = [safe.name, safe.code, safe.message].filter(Boolean);
  return parts.join(': ') || 'Unknown error';
}

export function createTimedFetch({
  deadlineMs,
  fetchImpl = globalThis.fetch,
  onRecord = () => {},
  userAgent,
} = {}) {
  if (!(Number.isFinite(deadlineMs) && deadlineMs > 0)) throw new Error('deadlineMs must be a positive number');
  let sequence = 0;

  return async function timedFetch(url, init = {}, context = {}) {
    const startedAt = Date.now();
    const rpcMethod = boundedRpcMethod(context.rpcMethod);
    const record = {
      sequence: ++sequence,
      group: boundedText(context.group || 'unclassified'),
      hostname: null,
      pathname: null,
      method: String(init.method || 'GET').toUpperCase(),
      ...(rpcMethod ? { rpcMethod } : {}),
      elapsedMs: 0,
      deadlineMs,
      stage: 'parse',
      status: null,
      outcome: 'transport_error',
      responseHeaders: {},

View on GitHub (pinned to e586b8b4b8)