Hmbown/CodeWhale · error · Error
Invalid first pet bucket.
Error message
Invalid first pet bucket.
What it means
compilePetTelemetry() in pet-native.js validates its firstSequence parameter before compiling a pet replay timeline. firstSequence is the bin/sequence number the replay starts from, and must be a non-negative safe integer (whole milliseconds-based bucket index). The library throws this error when the caller passes a non-integer (fractional, NaN, Infinity), a negative number, or a value outside the safe-integer range.
Solutions
- Compute firstSequence with Math.floor and clamp: firstSequence = Math.max(0, Math.floor(raw));
- Validate before calling: Number.isSafeInteger(firstSequence) && firstSequence >= 0, defaulting to 0 when absent.
- If restoring from a persisted checkpoint, coerce/repair the stored value (or drop it and restart from 0) instead of passing it raw.
- Convert string/unknown inputs with Number() and reject non-numeric values before the call.
Example fix
// before compilePetTelemetry(events, durationMs, elapsedMs / PET_BIN_MS); // after const firstSequence = Math.max(0, Math.floor(elapsedMs / PET_BIN_MS)); compilePetTelemetry(events, durationMs, firstSequence);
Defensive patterns
Strategy: validation
Validate before calling
function isValidFirstSequence(n) {
return Number.isSafeInteger(n) && n >= 0;
}
if (!isValidFirstSequence(firstSequence)) firstSequence = 0; Type guard
const isStartBin = (v) => typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
Try / catch
try {
compilePetTelemetry(events, durationMs, firstSequence);
} catch (e) {
if (e.message === 'Invalid first pet bucket.') {
firstSequence = 0;
return compilePetTelemetry(events, durationMs, firstSequence);
}
throw e;
} Prevention
- Always derive bin indices with Math.floor from a millisecond division
- Default optional sequence params to 0 with ?? 0
- Validate persisted checkpoints before reusing stored sequence numbers
When it happens
Trigger: Calling compilePetTelemetry(input, durationMs, firstSequence) with firstSequence set to a negative number, a fractional value (e.g. computed via division without Math.floor), NaN/Infinity (e.g. from a failed lookup or JSON parse of 'null'), or a non-number (string from a query param).
Common situations: Restoring a checkpoint saved by a different version where the sequence field is null; computing a start bin as (timeMs / binMs) with timeMs undefined so the result is NaN; passing a user-supplied offset string from UI state without Number() conversion; integer overflow beyond Number.MAX_SAFE_INTEGER after multiplying a large timestamp.
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 clock origin.
- maxBins must be an integer in [16, 1048576].
- Archive the legacy recording before accepting more…
- Choose an appearance file smaller than 4 KiB.
- invalid_container
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/7840ffddef8d46a9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/pet-native.js:1173
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));
const events = [...unique.values()].filter(e => !isContainer(e)
&& !(e.category === 'orchestration' && parents.has(e.id)))View on GitHub (pinned to 73e0f67d83)