Hmbown/CodeWhale · error · Error

Invalid pet clock origin.

Error message

Invalid pet clock origin.

What it means

The pet replay ingestor in pet-native.js validates a numeric clock origin via Number.isFinite(originMs) before replaying events. This error means the originMs argument passed to the pet build/score entry point is not a finite number (NaN, Infinity, undefined, string, etc.). The library throws early so bin math (durations and timestamps shifted by originMs) stays well-defined.

Solutions

  1. Pass a finite epoch-milliseconds number as originMs, e.g. Date.parse(traceStart) for a date string.
  2. Check the value with Number.isFinite(originMs) at the call site before invoking the API.
  3. If the origin comes from config or metadata, verify it is present and numeric; fall back to 0 for a zero-based trace.

Example fix

// before
buildPet(trace, { originMs: trace.startTimeISO });
// after
buildPet(trace, { originMs: Date.parse(trace.startTimeISO) });
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isFinite(originMs)) throw new TypeError('originMs must be a finite number');
const origin = typeof origin === 'string' ? Date.parse(origin) : origin;

Type guard

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

Prevention

When it happens

Trigger: Calling the pet replay/builder function with an originMs argument that is NaN, Infinity, null, or a non-numeric value (e.g. a Date object not converted with .getTime(), or an undefined variable).

Common situations: Developers passing Date objects or ISO strings instead of epoch milliseconds, reading the origin from an unpopulated config field, or JSON round-trips that turned a number into null.

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

Appendix: source

Thrown at pet/ios/Resources/pet-native.js:1175

    }
}
exports.PetLiveTape = PetLiveTape;
const order = (a, b) => a < b ? -1 : a > b ? 1 : 0;
const keyOf = (e) => JSON.stringify([e.traceId, e.id]);
const isContainer = (e) => e.attributes['whalesong.container'] === true
    || e.attributes['codewhale.container'] === true;
/** Compile a single trace. Unknown-duration spans provide onsets, not occupancy.
 * 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

View on GitHub (pinned to 433685b202)