Hmbown/CodeWhale · error · Error

Archive the legacy recording before accepting more…

Error message

Archive the legacy recording before accepting more telemetry.

What it means

PetWorld's `tapeLog` is a fixed-capacity in-memory recording of pet telemetry frames; when the incoming sequence number reaches 216,000 (the hardcoded archive threshold), the world refuses to append more entries. The library throws this to force callers to offload/persist older frames instead of letting the buffer grow unbounded in the iOS native bridge.

Solutions

  1. Archive (persist and clear) the legacy recording before the sequence reaches 216,000 — rotate `tapeLog` in your session lifecycle, e.g. dump to disk and start a new PetWorld with sequence 0.
  2. Check `world.tapeLog.length` (or your current sequence) on a timer or per-step and trigger archiving below the threshold, e.g. at 200,000 frames.
  3. For replay/testing, clamp or remap sequence numbers to stay below the cap instead of feeding raw counters.

Example fix

// before
world.record(nextSequence, frame); // nextSequence grows past 216_000 -> throws
// after
if (nextSequence >= 200_000) {
  archiveTape(world.tapeLog);      // persist legacy recording
  world = new PetWorld();          // restart at sequence 0
}
world.record(nextSequence, frame);
Defensive patterns

Strategy: validation

Validate before calling

function canAcceptSequence(seq) { return Number.isSafeInteger(seq) && seq >= 0 && seq < 216_000; }

Try / catch

try { world.record(seq, frame); } catch (e) { if (e.message.includes('Archive the legacy recording')) { archiveTape(world.tapeLog); world = new PetWorld(); } else throw e; }

Prevention

When it happens

Trigger: Calling the recording/append API of `PetWorld` (public) with a sequence number >= 216,000 — e.g. continuously feeding frames for a long-running simulation without ever trimming or archiving `tapeLog`, or inserting at a large sequence index directly.

Common situations: Long-lived pet sessions (216,000 frames at 400 ms sim-time each is ~24 hours of continuous telemetry) where the app never rotates the tape; replay tooling that seeds a huge starting sequence; clock/simulator drift pushing sequences past the cap.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/5bda3c35af8de8d9. Report an issue: GitHub.

Appendix: source

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

        this.interactionLog.push({ timeMs: (this.tick + 1) * 1000 / HZ, kind, x, y });
    }
    /** Accept a live source packet at the next 400ms boundary. The accepted tape,
     * including any missing intervals, is the exact replay authority for this host. */
    acceptTelemetry(input) {
        (0, pet_telemetry_js_1.validatePetBucket)(input);
        const sequence = Math.floor(this.tick / 12) + 1;
        if (this.tapeLog.length >= 216_000)
            throw new Error('Archive this pet recording before accepting more telemetry.');
        this.hasTelemetry = true;
        if (this.segmented) {
            const at = this.tapeLog.findIndex(b => b.sequence >= sequence);
            const index = at < 0 ? this.tapeLog.length : at;
            this.tapeLog.splice(index, at >= 0 && this.tapeLog[at].sequence === sequence ? 1 : 0, { ...structuredClone(input), sequence, simTimeMs: sequence * 400 });
            this.hashTape(index);
            return;
        }
        if (sequence >= 216_000)
            throw new Error('Archive the legacy recording before accepting more telemetry.');
        const changedFrom = Math.min(sequence, this.tapeLog.length);
        while (this.tapeLog.length <= sequence) {
            const at = this.tapeLog.length;
            this.tapeLog.push({ version: 1, sequence: at, simTimeMs: at * 400, durationMs: 400,
                activity: .12, coherence: .25, attention: 0, channel: 'other', observed: 0, roamX: 0, roamY: 0, flip: 1, lit: 1,
                onsets: Array(13).fill(0), activeMs: Array(13).fill(0), errors: 0, agentIds: [], waiting: false });
        }
        this.tapeLog[sequence] = { ...structuredClone(input), sequence, simTimeMs: sequence * 400 };
        this.hashTape(changedFrom);
    }
    /** dt is bounded so suspending a surface cannot cause an unbounded catch-up. */
    step(dt, opts = { motion: true, sensitivity: 1 }) {
        if (!Number.isFinite(dt) || dt < 0 || dt > 10)
            throw new Error('World dt must be in [0, 10] seconds.');
        this.accumulator += dt;
        this.voices = [];
        while (this.accumulator + 1e-10 >= 1 / HZ) {
            this.accumulator -= 1 / HZ;

View on GitHub (pinned to 433685b202)