Hmbown/CodeWhale · error · Error
Engine pet clock jump.
Error message
Engine pet clock jump.
What it means
In pet-watch's advanceEngine, the world clock derives engineTick from frame.timeMs and feeds it to PetEngineTelemetry; this error fires when the engine telemetry model rejects the resulting clock movement (a backward or otherwise unrepresentable tick jump), because letting the pet simulation continue would desynchronize its state from the recorded engine telemetry.
Solutions
- Provide non-empty text, e.g. {action:"type", text:"hello world"}.
- If the intent was to press Enter/Tab etc., use the key tool instead of browser type.
- Guard the source string: only call when typeof text === "string" && text.length > 0.
Example fix
// before
resolveTool("browser", { action: "type", text: "" });
// after
resolveTool("browser", { action: "type", text: "hello world" }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof text !== "string" || text.length === 0) {
throw new Error("browser type requires non-empty text");
} Type guard
const typableText = (t) => typeof t === "string" && t.length > 0;
Prevention
- Guard upstream tool results — an empty result should skip the type call, not send "".
- Use the key tool for key presses; browser type is for literal text only.
- Default interpolated variables to a checked fallback before building args.
When it happens
Trigger: resolveTool("browser", {action:"type"}) with text missing/undefined, text: null, text: 42, or text: "" (zero length).
Common situations: A model emitting an empty text field when the actual text should come from a previous tool result that returned nothing; interpolated variable that was undefined/empty string; confusing type (types literal text) with press/keys (which types key names).
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid Engine batch.
- Invalid pet raster size.
- Native habitat exceeds 8 MiB.
- No pet segment was prepared.
- Pet checkpoint exceeds its size limit.
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/870d101aad1215dd.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/pet-native.js:106
this.engineTick = Math.round(this.world.frame.timeMs * 30 / 1000);
this.engine = new pet_engine_js_1.PetEngineTelemetry();
this.world.voices = [];
return this.world.frame.timeMs;
}
observeEngine(metadataJSON, timeMs) { this.engine.observe(JSON.parse(metadataJSON), timeMs); }
observeEngineBatch(metadataJSON, timeMs) {
const events = JSON.parse(metadataJSON);
if (!Array.isArray(events) || events.length > 64)
throw new Error('Invalid Engine batch.');
const next = this.engine.clone();
for (const event of events)
next.observe(event, timeMs);
this.engine = next;
}
advanceEngine(timeMs, motion, waiting) {
const target = Math.floor(timeMs * 30 / 1000 + 1e-8);
if (!Number.isFinite(timeMs) || target < this.engineTick || target - this.engineTick > 300)
throw new Error('Engine pet clock jump.');
this.engine.confirmWaiting(timeMs, waiting);
const voices = [];
while (this.engineTick < target) {
if ((this.engineTick + 1) % 12 === 0)
this.world.acceptTelemetry(this.engine.bucket(Math.floor(this.engineTick / 12)));
this.world.step(1 / 30, { motion, sensitivity: 1 });
voices.push(...this.world.voices);
this.engineTick++;
}
this.world.voices = voices;
}
terminal(width, height) {
if (![width, height].every(n => Number.isSafeInteger(n) && n >= 1 && n <= 512))
throw new Error('Invalid pet raster size.');
const { sim, frame } = this.world, l = (0, pet_sim_js_1.layout)(width * 2, height * 4, frame.state);
const cells = Array(width * height).fill(0), bits = [[1, 8], [2, 16], [4, 32], [64, 128]];
sim.p.forEach((p, i) => {
if (frame.state.observed < .92 && i % 2 === 1)View on GitHub (pinned to 73e0f67d83)