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

The pet ingestor requires events already validated as event-v1 schema (schemaVersion 1, non-empty id/traceId, known category, finite non-negative startTime <= endTime, present attributes). Raw or malformed event objects are rejected with this message, telling you to run them through importTrace first. This keeps replay determinism by guaranteeing a uniform event shape.

Solutions

  1. Route your events through importTrace to normalize them into event-v1 objects before building a pet.
  2. Check each event: schemaVersion === 1, id, traceId, category in CATEGORIES, finite startTime/endTime with startTime >= 0 and endTime >= startTime, and a non-null attributes object.
  3. Re-export your trace with a current exporter if it predates event-v1.

Example fix

// before
buildPet(rawSpans);
// after
const events = importTrace(rawSpans);
buildPet(events, { originMs: 0 });
Defensive patterns

Strategy: validation

Validate before calling

const ok = events.every(e => e.schemaVersion === 1 && e.id && e.traceId
  && CATEGORIES.includes(e.category)
  && Number.isFinite(e.startTime) && Number.isFinite(e.endTime)
  && e.startTime >= 0 && e.endTime >= e.startTime && e.attributes);
if (!ok) events = importTrace(rawEvents);

Type guard

const isEventV1 = (e) => !!e && e.schemaVersion === 1 && typeof e.id === 'string' && typeof e.traceId === 'string' && typeof e.attributes === 'object';

Try / catch

try { buildPet(events) } catch (err) { if (err.message.includes('event-v1')) events = importTrace(events); else throw err; }

Prevention

When it happens

Trigger: Passing events that were constructed by hand or parsed from a foreign trace format directly into the pet builder instead of the importTrace pipeline; also any single field missing (attributes omitted, schemaVersion missing/2, negative startTime, endTime before startTime).

Common situations: Mixing raw OTel spans or custom log records into a pet call, skipping the normal import flow, or working with an older trace export produced before the event-v1 schema.

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@433685b202 (2026-09-15). Data as JSON: /api/errors/708092c893eb5101. Report an issue: GitHub.

Appendix: source

Thrown at pet/ios/Resources/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 433685b202)