Hmbown/CodeWhale · error · Error

World requires contiguous version 1 pet buckets.

Error message

World requires contiguous version 1 pet buckets.

What it means

The PetWorld constructor enforces bucket sequence contiguity. In unsegmented mode each tape bucket's sequence must equal its index (0,1,2,...); in segmented mode sequences must be strictly increasing. Each bucket must also pass validatePetBucket (version 1 schema). Any deviation means the telemetry tape cannot be replayed deterministically, so construction fails.

Solutions

  1. Renumber bucket.sequence to match the array index (or strictly increasing for segmented mode) before constructing.
  2. Re-export the tape from the original source instead of splicing recordings together.
  3. Run validatePetBucket on each element and drop/repair failing buckets, then renumber.
  4. Verify both producer and consumer agree on bucket schema version 1.

Example fix

// before
const tape = loadedTape.filter(b => !b.corrupt); // sequence now has gaps
const world = new PetWorld(points, tape); // throws
// after
const tape = loadedTape.filter(b => isValidV1(b)).map((b, i) => ({ ...b, sequence: i }));
const world = new PetWorld(points, tape);
Defensive patterns

Strategy: validation

Validate before calling

function isContiguousV1Tape(tape, segmented) {
  return tape.every((b, i) => validatePetBucket(b) &&
    (segmented ? i === 0 || b.sequence > tape[i - 1].sequence : b.sequence === i));
}

Type guard

const isV1Bucket = (b) => b != null && b.version === 1 && Number.isInteger(b.sequence) && b.sequence >= 0;

Try / catch

try {
  world = new PetWorld(points, tape, interactions);
} catch (e) {
  if (e.message.includes('contiguous version 1 pet buckets')) {
    const repaired = tape.filter(isV1Bucket).map((b, i) => ({ ...b, sequence: i }));
    world = new PetWorld(points, repaired, interactions);
  } else throw e;
}

Prevention

When it happens

Trigger: Constructing PetWorld with a tape whose bucket sequences have gaps or duplicates, buckets out of order, buckets from different recordings spliced together, or buckets not conforming to the version 1 schema caught by validatePetBucket.

Common situations: Manually editing or partially deleting telemetry buckets; merging two recordings whose sequences overlap; a producer upgrading bucket format while the consumer still expects version 1; off-by-one when regenerating tape after dropping corrupted buckets.

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

Appendix: source

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

    get startTimeMs() { return this.origin?.frame.timeMs ?? 0; }
    get endTimeMs() { return Math.max(this.frame.timeMs, (this.tapeLog.at(-1)?.simTimeMs ?? 0) + 400); }
    get needsSegment() {
        return !this.segmented && this.tapeLog.length < 1024 && this.interactionLog.length < 4096
            || this.bucketIndex >= 1024 || this.interactionIndex >= 4096;
    }
    constructor(points, tape = [], interactions = [], expressionVersion = 2, segmented = false) {
        if (tape.length > 216_000 || interactions.length > 100_000)
            throw new Error('Pet recording exceeds its input limit.');
        this.sim = new pet_sim_js_1.PetSim(points, 0xC0FFEE, expressionVersion);
        this.segmented = segmented;
        this.hasTelemetry = tape.length > 0;
        this.tapeLog = structuredClone([...tape]);
        this.interactionLog = structuredClone([...interactions]);
        for (let i = 0; i < this.tape.length; i++) {
            const b = this.tape[i];
            (0, pet_telemetry_js_1.validatePetBucket)(b);
            if (segmented ? i > 0 && b.sequence <= this.tape[i - 1].sequence : b.sequence !== i)
                throw new Error('World requires contiguous version 1 pet buckets.');
        }
        for (let i = 0; i < this.interactionLog.length; i++) {
            const e = this.interactionLog[i];
            if (!Number.isFinite(e.timeMs) || e.timeMs < 0 || i > 0 && e.timeMs < this.interactionLog[i - 1].timeMs
                || !['attention', 'food'].includes(e.kind) || !Number.isFinite(e.x) || !Number.isFinite(e.y)
                || Math.abs(e.x) > 1 || Math.abs(e.y) > 1)
                throw new Error('Invalid pet interaction.');
        }
        this.hashTape(0);
        this.frame = this.makeFrame(0);
        this.voices = this.score.voices(this.frame);
        if (segmented)
            this.origin = this.checkpoint();
    }
    checkpoint() {
        return structuredClone({ petCheckpointVersion: this.segmented ? 2 : 1,
            ...(this.segmented ? { historyStart: (this.origin?.tick ?? this.tick), hasTelemetry: this.hasTelemetry } : {}), history: this.historyDigest(),
            sim: this.sim.checkpoint(), score: this.score.checkpoint(), accumulator: this.accumulator,

View on GitHub (pinned to 433685b202)