Hmbown/CodeWhale · error · Error

This import contains more than

Error message

This import contains more than ${maxTraces} traces. Split it by trace ID.

What it means

A single import may contain at most options.maxTraces (default 8, hard cap 64) distinct trace IDs. When the input's trace count exceeds that, importTrace aborts and asks you to split the file by trace ID, keeping memory and UI cost bounded per import.

Solutions

  1. Split the file by trace ID and import each group with its own importTrace call.
  2. Raise options.maxTraces (integer, max 64) to fit the trace count.
  3. Filter the export to only the traces you need before importing.

Example fix

// before
importTrace(text, name, { maxTraces: 8 }); // file has 20 traces
// after
importTrace(text, name, { maxTraces: 64 }); // or split by trace ID
Defensive patterns

Strategy: validation

Validate before calling

const traceIds = new Set(events.map(e => e.traceId));
if (traceIds.size > 64) throw new Error(`${traceIds.size} traces exceed the 64-trace cap; split the file.`);

Try / catch

try {
  importTrace(text, name, { maxTraces });
} catch (e) {
  if (e instanceof Error && e.message.includes('Split it by trace ID')) {
    console.error(`File has more than ${maxTraces} traces; split or raise maxTraces (<=64).`);
  }
}

Prevention

When it happens

Trigger: importTrace on a combined export containing more distinct traceId values than maxTraces (e.g. 20 traces with default 8); lowering maxTraces below the actual trace count in the file.

Common situations: Exporting a whole service's spans instead of selected traces; concatenating many exports; a caller setting maxTraces to 1 to import one trace at a time but passing a multi-trace file.

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/cff5b22beb53945b. Report an issue: GitHub.

Appendix: source

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

    trace.events = trace.events.map(e => privacyEvent(e, mode));
    return [trace];
  }
  const isOTLP = Array.isArray(root.resourceSpans);
  let all: WhaleEvent[], origins = new Map<string, string>(), warnings: string[] = [];
  if (isOTLP) { const r = fromOTLP(root, maxEvents); all = r.events; origins = r.origins; warnings = r.warnings; }
  else {
    const incoming = records ?? [safe];
    if (incoming.length > maxEvents) throw new Error(`Import exceeds the ${maxEvents.toLocaleString()} event limit.`);
    all = incoming.map(normalizedEvent);
  }
  if (!all.length) throw new Error('The file contains no events.');
  const groups = new Map<string, WhaleEvent[]>(), ids = new Set<string>();
  for (const e of all) {
    const key = `${e.traceId}\0${e.id}`;
    if (ids.has(key)) throw new Error(`Duplicate event identity (${e.traceId}, ${e.id}). Import cancelled.`);
    ids.add(key);
    const group = groups.get(e.traceId) ?? []; group.push(privacyEvent(e, mode)); groups.set(e.traceId, group);
    if (groups.size > maxTraces) throw new Error(`This import contains more than ${maxTraces} traces. Split it by trace ID.`);
  }
  return [...groups].map(([id, events]) => {
    events.sort((a, b) => a.startTime - b.startTime || a.id.localeCompare(b.id));
    const base = isOTLP ? 0 : events[0].startTime;
    if (!isOTLP && events.some(e => Math.abs(e.endTime - base) > Number.MAX_SAFE_INTEGER)) throw new Error('Trace duration exceeds safely representable milliseconds.');
    for (const e of events) {
      if (e.attributes['whalesong.error_onset_ms'] !== undefined) e.attributes['whalesong.error_onset_ms'] = errorOnsetOf(e) - base;
      e.startTime -= base; e.endTime -= base;
    }
    const localIds = new Set(events.map(e => e.id)), missingParents = events.filter(e => e.parentId && !localIds.has(e.parentId)).length;
    const traceWarnings = [...warnings];
    if (missingParents) traceWarnings.push(`${missingParents} parent spans are absent from this trace; no parent relationship was invented.`);
    if (events.some(e => e.openEnded)) traceWarnings.push('Open spans have unknown duration and are displayed as onset-only, not extended into invented activity.');
    const currencies = new Set(events.filter(e => e.cost !== undefined).map(e => e.costCurrency ?? 'unspecified'));
    if (currencies.size > 1) traceWarnings.push('Mixed cost currencies: aggregate cost comparison is disabled.');
    return { id, name: groups.size > 1 ? `${filename} · ${id.slice(0, 8)}` : String(root.name ?? filename),
      events, duration: Math.max(1, events.reduce((m, e) => Math.max(m, e.endTime, e.startTime, e.status === 'error' ? errorOnsetOf(e) : 0), 0)),
      originTime: origins.get(id) ?? (root.originTime !== undefined && base === 0 ? str(root.originTime) : `${base} ms`),

View on GitHub (pinned to 433685b202)