Hmbown/CodeWhale · error · Error
Invalid pet duration.
Error message
Invalid pet duration.
What it means
compilePetTelemetry requires durationMs to be a finite, non-negative number of milliseconds; anything else (NaN, Infinity, negative) is rejected because bucket allocation is derived arithmetically from it. originMs is subtracted afterwards, so the raw value must still be valid on its own.
Solutions
- Coerce the duration before calling: Number.isFinite(d) && d >= 0, else clamp to 0.
- Fix the upstream timestamp so end - start is a valid non-negative number of ms.
- Sanitize JSON-sourced durations with Number(...) and reject NaN at parse time.
- Normalize clock sources (use a single monotonic clock) to avoid skew-induced negatives.
Example fix
// before compilePetTelemetry(events, endTs - startTs); // after const d = Number(endTs) - Number(startTs); compilePetTelemetry(events, Number.isFinite(d) && d >= 0 ? d : 0, firstSequence, originMs);
Defensive patterns
Strategy: validation
Validate before calling
const d = end - start;
if (!Number.isFinite(d) || d < 0) throw new Error('bad duration'); // fix timestamps upstream
compilePetTelemetry(events, d, firstSequence, originMs); Type guard
const isValidDuration = (d) => typeof d === 'number' && Number.isFinite(d) && d >= 0;
Try / catch
try { compilePetTelemetry(events, durationMs, firstSequence, originMs); }
catch (e) { if (e.message === 'Invalid pet duration.') { compilePetTelemetry(events, 0, firstSequence, originMs); } else throw e; } Prevention
- Compute durations from a single monotonic clock to avoid skew negatives.
- Check timestamps are initialized before subtracting.
- Coerce JSON-sourced durations with Number() and reject NaN at the boundary.
- Clamp with Math.max(0, d) when a zero duration is acceptable.
When it happens
Trigger: Passing durationMs as NaN/Infinity/negative — e.g. computing it from an unset end timestamp (undefined - start = NaN), a failed Date parse, a negative elapsed due to clock skew, or passing seconds instead of milliseconds producing a wrong-but-finite value (that one won't throw; NaN/negative will).
Common situations: Clock skew between producer and consumer making end<start; uninitialized end-time fields; string durations ('1200') from JSON that slipped through; new Date('garbage').getTime().
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
- Invalid pet duration.
- Invalid Engine pet clock.
- Invalid Engine pet metadata.
- Invalid Engine pet metadata.
- Invalid Engine pet metadata fields.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/9e011acdd245c734.
Report an issue: GitHub.
Appendix: source
Thrown at pet/ios/Resources/pet-native.js:1171
this.sequence = packet.sequence;
if (previous === undefined || packet.sequence <= previous)
return;
return packet;
}
}
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));View on GitHub (pinned to 433685b202)