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

  1. Compute firstSequence with Math.floor and clamp: firstSequence = Math.max(0, Math.floor(raw));
  2. Validate before calling: Number.isSafeInteger(firstSequence) && firstSequence >= 0, defaulting to 0 when absent.
  3. If restoring from a persisted checkpoint, coerce/repair the stored value (or drop it and restart from 0) instead of passing it raw.
  4. 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

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


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)