Hmbown/CodeWhale · error · Error

maxTraces must be in [1, 64].

Error message

maxTraces must be in [1, 64].

What it means

importTrace validates every option up front so malformed imports fail before any parsing work. maxTraces controls how many distinct trace IDs a single import may contain, and must be an integer between 1 and 64. Passing a non-integer, zero, negative, or >64 value throws this error immediately.

Solutions

  1. Pass an integer maxTraces between 1 and 64, e.g. importTrace(text, name, { maxTraces: 32 }).
  2. Clamp or round user-supplied values before calling: Math.min(64, Math.max(1, Math.round(value))).
  3. Omit maxTraces entirely to use the default of 8.

Example fix

// before
importTrace(text, name, { maxTraces: userInput });
// after
const maxTraces = Math.min(64, Math.max(1, Math.round(userInput ?? 8)));
importTrace(text, name, { maxTraces });
Defensive patterns

Strategy: validation

Validate before calling

const n = opts.maxTraces;
if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 64)) throw new Error('maxTraces must be an integer in [1, 64]');

Type guard

function isValidMaxTraces(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 64;
}

Try / catch

try {
  importTrace(text, name, { maxTraces });
} catch (e) {
  if (e instanceof Error && e.message.startsWith('maxTraces must be')) {
    console.error(`Bad option maxTraces=${maxTraces}: use an integer 1-64`);
  }
}

Prevention

When it happens

Trigger: Calling importTrace(text, name, { maxTraces: 0 }) or { maxTraces: 100 } or a non-integer like 2.5; maxTraces defaults to 8 so only explicit options trigger it.

Common situations: Config derived from user input or environment variables without clamping; computing maxTraces from another count (e.g. traces.length) that can exceed 64; arithmetic producing fractional values.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/8e037c708aabf12f. Report an issue: GitHub.

Appendix: source

Thrown at pet/src/core/ingest.ts:223

    for (const [i, record] of list(s.events).entries()) {
      const ea = attributes(record.attributes), time = Number(ns(record.timeUnixNano, 'event.timeUnixNano') - origin) / 1e6;
      const ename = String(record.name ?? 'span event');
      events.push({ schemaVersion: 1, id: `${s.spanId}/event/${i}`, traceId: s.traceId, parentId: s.spanId,
        startTime: time, endTime: time, agentId: e.agentId, name: ename, category: categoryFor(ename, ea),
        status: ename === 'exception' ? 'error' : 'unknown', attributes: ea, raw: { event: record, spanId: s.spanId, resource: rec.resource, scope: rec.scope } });
    }
    if (events.length > maxEvents) throw new Error(`Import exceeds the ${maxEvents.toLocaleString()} event limit, including span events.`);
  }
  return { events, origins: new Map([...bases].map(([k, v]) => [k, v.toString()])), warnings };
}

/** Parse strictly: malformed lines or duplicate identities never disappear silently. */
export function importTrace(text: string, filename = 'Imported trace', options: ImportOptions = {}): Trace[] {
  const mode = options.privacy ?? 'redact', maxEvents = options.maxEvents ?? 250_000;
  if (!['redact', 'metadata', 'retain'].includes(mode)) throw new Error('Unknown privacy mode.');
  const maxTraces = options.maxTraces ?? 8;
  if (!Number.isInteger(maxEvents) || maxEvents < 1 || maxEvents > 250_000) throw new Error('maxEvents must be in [1, 250000].');
  if (!Number.isInteger(maxTraces) || maxTraces < 1 || maxTraces > 64) throw new Error('maxTraces must be in [1, 64].');
  if (new TextEncoder().encode(text).length > (options.maxBytes ?? 64 * 1024 * 1024)) throw new Error('File exceeds the 64 MiB MVP import limit. Split the export by trace.');
  const trimmed = text.replace(/^\uFEFF/, '').trim();
  if (!trimmed) throw new Error('The trace file is empty.');
  let document: unknown;
  try { document = JSON.parse(trimmed); }
  catch {
    document = trimmed.split(/\r?\n/).filter(l => l.trim()).map((line, i) => {
      try { return JSON.parse(line); } catch { throw new Error(`Invalid JSON on nonempty line ${i + 1}. Import cancelled; no rows were skipped.`); }
    });
  }
  // Transform before both normalization and raw retention, so raw cannot bypass redaction.
  const safe = mode === 'retain' ? (options.redactor ? options.redactor(document, '') : document) : redact(document, '', options.redactor);
  const root = obj(safe);
  if(root.format === 'whalesong.evidence/v1') return [evidenceToTrace(validateBundle(root, Math.min(maxEvents, 100_000)))];
  if (isCodewhaleSession(safe)) {
    const trace = fromCodewhaleSession(safe, filename, maxEvents);
    trace.privacy = mode;
    trace.events = trace.events.map(e => privacyEvent(e, mode));

View on GitHub (pinned to 433685b202)