Hmbown/CodeWhale · error · Error
No pet segment was prepared.
Error message
No pet segment was prepared.
What it means
commitSegment() finalizes a recording segment previously created by prepareSegment(). The bridge stores the pending segment in this.segment; if commitSegment() is called without a prior prepareSegment(), or after the segment was already committed (which resets this.segment to undefined), there is nothing to commit and the bridge throws.
Solutions
- Call prepareSegment() and confirm it returned a recording JSON before calling commitSegment().
- Guard with needsSegment() before the prepare/commit pair and ensure it runs once per segment.
- Check whether a restoreCheckpoint/restoreRecording call reset the bridge state between prepare and commit.
- Deduplicate the commit callback so commitSegment() only runs once per segment.
Example fix
// before
bridge.prepareSegment();
bridge.commitSegment();
bridge.commitSegment(); // throws: segment already consumed
// after
if (bridge.needsSegment()) {
bridge.prepareSegment();
bridge.commitSegment(); // exactly once
} Defensive patterns
Strategy: type-guard
Validate before calling
if (bridge.needsSegment()) {
bridge.prepareSegment();
pendingSegment = true;
}
// later, once:
if (pendingSegment) { bridge.commitSegment(); pendingSegment = false; } Type guard
function canCommit(bridge, pendingSegment) {
return pendingSegment === true && typeof bridge.prepareSegment === 'function';
} Try / catch
try {
bridge.commitSegment();
} catch (e) {
if (e.message === 'No pet segment was prepared.') {
// segment already committed or consumed by a restore; reset local flag
pendingSegment = false;
} else throw e;
} Prevention
- Track pending-segment state locally and commit exactly once.
- Re-prepare after any restoreCheckpoint/restoreRecording call, which clears the pending segment.
- Deduplicate completion callbacks that could double-commit.
When it happens
Trigger: Calling commitSegment() when needsSegment()/prepareSegment() was never invoked, or calling commitSegment() twice in a row (the first call sets this.segment = undefined), or after restoreRecording()/restoreCheckpoint() which also clears this.segment.
Common situations: Race between the recording UI and a checkpoint restore that wiped the pending segment; double-commit on a completion callback firing twice; forgetting to call prepareSegment() after needsSegment() returned true.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- No pet segment was prepared.
- Only a live recording can resume observation.
- This Runtime already owns a task execution manager
- A cancelled Operation cannot be edited.
- Agent not found
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/2566c5f24f278949.
Report an issue: GitHub.
Appendix: source
Thrown at pet/ios/Resources/pet-native.js:66
}
/** Losing a producer invalidates outstanding coverage, never the creature. */
disconnectEngine() { this.engine = new pet_engine_js_1.PetEngineTelemetry(); this.world.voices = []; }
interact(kind, x, y) { this.world.interact(kind, x, y); }
interactions() { return JSON.stringify(this.world.interactions); }
accept(packet) { this.world.acceptTelemetry(JSON.parse(packet)); }
acceptLiveTail(text) {
const packet = this.liveTape.readTail(text);
if (!packet)
return false;
this.world.acceptTelemetry(packet);
return true;
}
resetLiveInput() { this.liveTape.reset(); return this.resumeEngine(); }
recording(withCheckpoint = false) { return JSON.stringify(this.world.recording(withCheckpoint)); }
needsSegment() { return this.world.needsSegment; }
prepareSegment() { this.segment = this.world.prepareSegment(); return JSON.stringify(this.segment.recording); }
commitSegment() { if (!this.segment)
throw new Error('No pet segment was prepared.'); this.segment.commit(); this.segment = undefined; }
checkpoint() { return JSON.stringify(this.world.checkpoint()); }
recordingChunk(index, completed = false) { return this.world.recordingChunk(index, completed); }
restoreCheckpoint(text) {
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) {
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]);
this.world = pet_world_js_1.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 pet_engine_js_1.PetEngineTelemetry();
}
/** Resume a live host at the first unrecorded bucket. Keep every acceptedView on GitHub (pinned to 433685b202)