Hmbown/CodeWhale · error · Error

Invalid event-v1 pet input. Import through importTrace…

Error message

Invalid event-v1 pet input. Import through importTrace first.

What it means

compilePetTelemetry() requires its input to already be normalized event-v1 objects (schemaVersion === 1 with id, traceId, a known category, finite non-negative start/end times, and attributes). The library throws this error when any event in the input array fails that shape check, telling the caller to run the raw data through importTrace() first, which produces valid event-v1 records.

Solutions

  1. Call importTrace() on the raw data first and pass its output to compilePetTelemetry.
  2. Log/inspect the offending event (id, category, startTime, endTime, schemaVersion) to find which field violates the contract.
  3. Fix the producer so events carry schemaVersion 1, valid category strings, finite non-negative times with endTime >= startTime, and a non-null attributes object.
  4. If events come from an older schema, migrate/normalize them to event-v1 before compilation.

Example fix

// before
compilePetTelemetry(rawSpans, durationMs);
// after
const events = importTrace(rawSpans); // normalizes to event-v1
compilePetTelemetry(events, durationMs);
Defensive patterns

Strategy: validation

Validate before calling

const isEventV1 = (e) =>
  e.schemaVersion === 1 && !!e.id && !!e.traceId &&
  Number.isFinite(e.startTime) && Number.isFinite(e.endTime) &&
  e.startTime >= 0 && e.endTime >= e.startTime && !!e.attributes;
if (!events.every(isEventV1)) events = importTrace(rawSpans);

Type guard

const isEventV1 = (e) =>
  typeof e === 'object' && e !== null &&
  e.schemaVersion === 1 && typeof e.id === 'string' &&
  typeof e.traceId === 'string' && CATEGORIES.includes(e.category) &&
  Number.isFinite(e.startTime) && Number.isFinite(e.endTime) &&
  e.startTime >= 0 && e.endTime >= e.startTime &&
  typeof e.attributes === 'object' && e.attributes !== null;

Try / catch

try {
  return compilePetTelemetry(events, durationMs);
} catch (e) {
  if (e.message.startsWith('Invalid event-v1 pet input')) {
    return compilePetTelemetry(importTrace(rawInput), durationMs);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing raw spans/trace rows (from an OTLP export, a JSON log, or a hand-built object) directly to compilePetTelemetry without importTrace; events missing attributes; endTime earlier than startTime; negative timestamps; category strings not in CATEGORIES (typos like 'orchstration').

Common situations: Skipping the documented importTrace step when wiring a custom data source; a producer upgraded its export schema (schemaVersion 2+) so old events fail the v1 check; deserialization dropping the attributes field; clock skew producing endTime < startTime.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/0a9e9ac7f420399e. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/pet_watch/pet-native.js:1183

 * Updates of the same trace/id replace earlier snapshots rather than double count.
 * An endpoint onset gets its own bucket; intervals use [start, end). */
function compilePetTelemetry(input, durationMs = 0, firstSequence = 0, originMs = 0) {
    if (input.length > 250_000)
        throw new Error('Pet input exceeds 250000 events.');
    if (!Number.isFinite(durationMs) || durationMs < 0)
        throw new Error('Invalid pet duration.');
    if (!Number.isSafeInteger(firstSequence) || firstSequence < 0)
        throw new Error('Invalid first pet bucket.');
    if (!Number.isFinite(originMs))
        throw new Error('Invalid pet clock origin.');
    durationMs = Math.max(0, durationMs - originMs);
    const unique = new Map();
    const traces = new Set();
    for (const e of input) {
        if (e.schemaVersion !== 1 || !e.id || !e.traceId || !model_js_1.CATEGORIES.includes(e.category)
            || !Number.isFinite(e.startTime) || !Number.isFinite(e.endTime)
            || e.startTime < 0 || e.endTime < e.startTime || !e.attributes)
            throw new Error('Invalid event-v1 pet input. Import through importTrace first.');
        traces.add(e.traceId);
        unique.set(keyOf(e), e);
    }
    if (traces.size > 1)
        throw new Error('Select one trace for the pet.');
    const parents = new Set([...unique.values()].filter(e => e.parentId).map(e => e.parentId));
    const events = [...unique.values()].filter(e => !isContainer(e)
        && !(e.category === 'orchestration' && parents.has(e.id)))
        .map(e => ({ ...e, startTime: e.startTime - originMs, endTime: (e.openEnded ? e.startTime : e.endTime) - originMs,
        attributes: e.attributes['whalesong.error_onset_ms'] === undefined ? e.attributes
            : { ...e.attributes, 'whalesong.error_onset_ms': (0, model_js_1.errorOnsetOf)(e) - originMs } }))
        .sort((a, b) => a.startTime - b.startTime || order(a.id, b.id));
    let lastOnset = 0;
    for (const e of events) {
        durationMs = Math.max(durationMs, e.endTime);
        lastOnset = Math.max(lastOnset, e.startTime);
    }
    const failures = events.filter(e => e.category === 'error' || e.status === 'error').map(model_js_1.errorOnsetOf).sort((a, b) => a - b);

View on GitHub (pinned to 73e0f67d83)