Hmbown/CodeWhale · error · Error

Invalid version 1 pet bucket.

Error message

Invalid version 1 pet bucket.

What it means

Each row of a version-1 pet tape (JSONL) must pass validatePetBucket: exact simTimeMs/durationMs derived from the sequence and PET_BIN_MS, a known channel category, boolean waiting, bounded agentIds and error counts, and exactly-13-length onsets/activeMs arrays with values in range. A bucket failing any of these checks throws this error, so malformed telemetry rows never enter the renderer.

Solutions

  1. Fix the tape producer so simTimeMs = sequence * PET_BIN_MS and durationMs = PET_BIN_MS for every row.
  2. Ensure every bucket's onsets and activeMs arrays have exactly 13 entries matching CHANNELS.
  3. Validate agentIds are non-empty strings <=4096 chars and drop oversized collections.
  4. Regenerate the tape from the same pet-native.js version that will decode it.

Example fix

// before
rows.push({ sequence: i, simTimeMs: i * 1000, durationMs: 1000, channel: 'unknown', waiting: false, agentIds: [], errors: 0, onsets: new Array(13).fill(0), activeMs: new Array(13).fill(0) })
// after
rows.push({ sequence: i, simTimeMs: i * PET_BIN_MS, durationMs: PET_BIN_MS, channel: CATEGORIES[0], waiting: false, agentIds: [], errors: 0, onsets: new Array(13).fill(0), activeMs: new Array(13).fill(0) })
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeV1Bucket(b, CATEGORIES, PET_BIN_MS) {
  const safeInt = (n, hi) => Number.isSafeInteger(n) && n >= 0 && n <= hi;
  return !!b && b.simTimeMs === b.sequence * PET_BIN_MS && b.durationMs === PET_BIN_MS
    && CATEGORIES.includes(b.channel) && typeof b.waiting === 'boolean'
    && Array.isArray(b.agentIds) && b.agentIds.length <= 250000 && b.agentIds.every(id => typeof id === 'string' && id && id.length <= 4096)
    && safeInt(b.errors, 250000) && Array.isArray(b.onsets) && b.onsets.length === 13 && b.onsets.every(n => safeInt(n, 250000))
    && Array.isArray(b.activeMs) && b.activeMs.length === 13 && b.activeMs.every(n => Number.isFinite(n) && n >= 0 && n <= 100000000);
}

Type guard

const isV1Bucket = (b) => typeof b === 'object' && b !== null && typeof b.sequence === 'number' && Array.isArray(b.onsets) && b.onsets.length === 13;

Try / catch

try { rows = decodePetJSONL(text); }
catch (e) { if (/Invalid version 1 pet bucket/.test(e.message)) { reportBadTape(e); rows = []; } else throw e; }

Prevention

When it happens

Trigger: Calling decodePetJSONL on a file where any row violates the v1 bucket schema: simTimeMs !== sequence*PET_BIN_MS, durationMs !== PET_BIN_MS, unknown channel, agentIds >250k or entries not strings/empty/>4096 chars, errors outside 0-250000, or onsets/activeMs arrays not exactly 13 long or containing out-of-range numbers.

Common situations: Producing the JSONL with a different bin duration than PET_BIN_MS; adding a 14th channel upstream while the tape validator still expects 13; log collector concatenating or rewriting rows; a producer bug writing durations in a different unit (seconds vs ms).

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/8377b348a7f288dc. Report an issue: GitHub.

Appendix: source

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

exports.encodePetJSONL = encodePetJSONL;
exports.encodePetTSV = encodePetTSV;
const model_js_1 = require("./model.js");
const signal_js_1 = require("./signal.js");
const pet_sim_js_1 = require("./pet-sim.js");
/** One projection for imports, demos and recorded live snapshots. Times are ms.
 * These are aesthetic encodings of measured events, never model confidence. */
exports.PET_BIN_MS = 400;
function validatePetBucket(value) {
    (0, pet_sim_js_1.validatePetState)(value);
    const b = value;
    if (!b || typeof b !== 'object' || b.version !== 1 || !Number.isSafeInteger(b.sequence) || b.sequence < 0 || b.sequence > pet_sim_js_1.PET_MAX_SECONDS * 2.5
        || b.simTimeMs !== b.sequence * exports.PET_BIN_MS || b.durationMs !== exports.PET_BIN_MS
        || !model_js_1.CATEGORIES.includes(b.channel) || typeof b.waiting !== 'boolean'
        || !Array.isArray(b.agentIds) || b.agentIds.length > 250_000 || b.agentIds.some(id => typeof id !== 'string' || !id || id.length > 4096)
        || !Number.isSafeInteger(b.errors) || b.errors < 0 || b.errors > 250_000
        || !Array.isArray(b.onsets) || b.onsets.length !== 13 || b.onsets.some(n => !Number.isSafeInteger(n) || n < 0 || n > 250_000)
        || !Array.isArray(b.activeMs) || b.activeMs.length !== 13 || b.activeMs.some(n => !Number.isFinite(n) || n < 0 || n > 100_000_000))
        throw new Error('Invalid version 1 pet bucket.');
}
function decodePetJSONL(text) {
    if (text.length > 64 * 1024 * 1024)
        throw new Error('Pet tape exceeds 64 MiB.');
    const rows = text.split(/\r?\n/).filter(line => line.trim()).map(line => JSON.parse(line));
    if (rows.length > 216_000)
        throw new Error('Pet tape exceeds 24 hours.');
    return rows.map((row, i) => { validatePetBucket(row); if (row.sequence !== i)
        throw new Error('Non-contiguous pet tape.'); return row; });
}
/** A live file must advance before its contents count as a new observation.
 * Existing bytes, duplicate samples and a restarted sequence establish a
 * baseline; they never replay an old onset or human request. Drivers supply a
 * bounded tail and reset this cursor after suspension or a new attachment. */
class PetLiveTape {
    sequence;
    reset() { this.sequence = undefined; }
    readTail(text) {

View on GitHub (pinned to 433685b202)