Hmbown/CodeWhale · error · Error
Pet checkpoint exceeds its size limit.
Error message
Pet checkpoint exceeds its size limit.
What it means
restoreCheckpoint(text) accepts a serialized checkpoint and, as a guard before parsing, enforces a hard 512 KiB limit on the input string. Larger checkpoints are rejected up front because checkpoints are meant to be small state snapshots, and oversized ones usually indicate corruption or the wrong payload being passed.
Solutions
- Pass the exact string returned by pet.checkpoint(), not recording output
- Check text.length <= 512*1024 before calling and split/truncate the payload if it is a composite blob
- Re-serialize the checkpoint compactly (strip debug fields, minify JSON)
- If you genuinely need more state, store it via restoreRecording (8 MiB limit) instead
Example fix
// before
pet.restoreCheckpoint(bigBlob);
// after
if (bigBlob.length > 512 * 1024) throw new Error('not a checkpoint?');
pet.restoreCheckpoint(bigBlob); Defensive patterns
Strategy: validation
Validate before calling
function canRestoreCheckpoint(text) { return typeof text === 'string' && text.length <= 512 * 1024; } Try / catch
try {
pet.restoreCheckpoint(text);
} catch (err) {
if (err.message === 'Pet checkpoint exceeds its size limit.') {
// wrong payload or corrupted checkpoint — recover from last good checkpoint
pet.restoreCheckpoint(lastGoodCheckpoint);
} else throw err;
} Prevention
- Store checkpoint() and recording() outputs under distinct keys
- Minify checkpoint JSON and strip debug fields before persisting
- Check length before restore and keep a rolling last-good checkpoint
When it happens
Trigger: Calling restoreCheckpoint with a string longer than 512*1024 characters — e.g. passing a full recording/habitat dump instead of a checkpoint, or a checkpoint serialized with an accidentally embedded recording.
Common situations: Mixing up checkpoint() output with recording() output; a producer bug that nests recordings inside checkpoints; checkpoints inflated by verbose debug fields.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- 1
- Fleet artifact exceeds the 16 MiB limit
- Invalid local connection file.
- Invalid pet particle checkpoint.
- Invalid pet particle checkpoint.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/03d45bfe5a014294.
Report an issue: GitHub.
Appendix: source
Thrown at pet/src/core/pet-native.ts:58
}
/** Losing a producer invalidates outstanding coverage, never the creature. */
disconnectEngine(): void { this.engine = new PetEngineTelemetry(); this.world.voices = []; }
interact(kind: PetInteraction['kind'], x: number, y: number): void { this.world.interact(kind, x, y); }
interactions(): string { return JSON.stringify(this.world.interactions); }
accept(packet: string): void { this.world.acceptTelemetry(JSON.parse(packet)); }
acceptLiveTail(text: string): boolean {
const packet = this.liveTape.readTail(text); if (!packet) return false;
this.world.acceptTelemetry(packet); return true;
}
resetLiveInput(): number { this.liveTape.reset(); return this.resumeEngine(); }
recording(withCheckpoint = false): string { return JSON.stringify(this.world.recording(withCheckpoint)); }
needsSegment(): boolean { return this.world.needsSegment; }
prepareSegment(): string { this.segment = this.world.prepareSegment(); return JSON.stringify(this.segment.recording); }
commitSegment(): void { if (!this.segment) throw new Error('No pet segment was prepared.'); this.segment.commit(); this.segment = undefined; }
checkpoint(): string { return JSON.stringify(this.world.checkpoint()); }
recordingChunk(index: number, completed = false): string | null { return this.world.recordingChunk(index, completed); }
restoreCheckpoint(text: string): void {
if (text.length > 512 * 1024) throw new Error('Pet checkpoint exceeds its size limit.');
this.restoreRecording(JSON.stringify({ ...this.world.recording(false), checkpoint: JSON.parse(text) }));
}
restoreRecording(text: string): void {
if (text.length > 8 * 1024 * 1024) throw new Error('Native habitat exceeds 8 MiB.');
const points = this.world.sim.p.map(p => [p.hx, p.hy] as [number, number]);
this.world = PetWorld.fromRecording(points, JSON.parse(text));
this.liveTape.reset();
this.segment = undefined; this.engineTick = Math.round(this.world.frame.timeMs * 30 / 1000); this.engine = new PetEngineTelemetry();
}
/** Resume a live host at the first unrecorded bucket. Keep every accepted
* interval, but never present its last observed frame as current evidence. */
resumeEngine(): number {
this.world.resumeObservation();
this.engineTick = Math.round(this.world.frame.timeMs * 30 / 1000);
this.engine = new PetEngineTelemetry();
this.world.voices = [];
return this.world.frame.timeMs;
}View on GitHub (pinned to 433685b202)