Hmbown/CodeWhale · error · Error
Invalid version 1 pet bucket.
Error message
Invalid version 1 pet bucket.
What it means
validatePetBucket checks each decoded version-1 pet bucket's shape: sequence-aligned simTimeMs and PET_BIN_MS durationMs, a channel present in CATEGORIES, boolean waiting, bounded agentIds (string, non-empty, <=4096 chars, <=250k), non-negative bounded errors count, and exactly 13-element onsets and activeMs arrays within bounds. A bucket failing any check throws 'Invalid version 1 pet bucket.'
Solutions
- Identify the offending row index from the JSONL file and log the full row; compare each field against the v1 constraints above.
- If the tape was written by another schema version, regenerate it with the current build instead of feeding it to the v1 validator.
- Repair specific defects: set simTimeMs = sequence * PET_BIN_MS, durationMs = PET_BIN_MS, pad/truncate onsets and activeMs to 13 elements, and drop invalid agentIds entries.
- Re-encode the tape after fixing, or discard the corrupt file and let the app rebuild it from the session log.
Example fix
// before
rows.map(JSON.parse).forEach(b => decodePetJSONL(b)); // b.onsets has 12 entries
// after
if (Array.isArray(b.onsets) && b.onsets.length === 13 &&
Array.isArray(b.activeMs) && b.activeMs.length === 13) {
decodePetJSONL(b);
} else {
b.onsets = new Array(13).fill(0);
b.activeMs = new Array(13).fill(0);
decodePetJSONL(b);
} Defensive patterns
Strategy: validation
Validate before calling
function bucketLooksValid(b, BIN_MS, CATEGORIES) {
return b && typeof b === 'object' &&
b.simTimeMs === b.sequence * BIN_MS && b.durationMs === BIN_MS &&
CATEGORIES.includes(b.channel) && typeof b.waiting === 'boolean' &&
Array.isArray(b.onsets) && b.onsets.length === 13 &&
Array.isArray(b.activeMs) && b.activeMs.length === 13 &&
Number.isSafeInteger(b.errors) && b.errors >= 0;
} Type guard
const isPetBucketV1 = (b, BIN_MS, CATEGORIES) => bucketLooksValid(b, BIN_MS, CATEGORIES);
Try / catch
try {
rows.forEach(validatePetBucket);
} catch (e) {
if (e.message === 'Invalid version 1 pet bucket.') rebuildTapeFromSessionLog();
else throw e;
} Prevention
- Write tapes only through the current encoder so field shapes always match the v1 validator.
- Keep onsets/activeMs exactly 13 elements at write time.
- Skip/drop rows with undefined fields instead of letting them reach the validator; log them for repair.
When it happens
Trigger: decodePetJSONL encountering a JSONL row whose bucket: has mismatched simTimeMs vs sequence*PET_BIN_MS, an unknown channel string, agentIds entries that are empty/oversized/non-string, negative errors, onsets/activeMs arrays of the wrong length (not 13) or containing out-of-range/NaN values.
Common situations: A pet tape file written by a different schema version (field renamed or missing, so the field is undefined and fails every typeof check); hand-assembled or corrupted rows; the v1 bucket written when PET_BIN_MS or the 13-channel layout differed from the current build.
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
- invalid persisted user image content kind
- Runtime Chat binding state uses an unsupported schema
- Codewhale terminal receipt contained a non-scalar field
- Duplicate .
- Duplicate policy identity.
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/9f25dde43a220fdf.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/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 73e0f67d83)