Hmbown/CodeWhale · error · Error

Pet checkpoint telemetry does not match its clock.

Error message

Pet checkpoint telemetry does not match its clock.

What it means

PetWorld independently verifies that the telemetry snapshot stored in the checkpoint equals the tape bucket the checkpoint's clock currently falls inside (candidate bucket where frame.timeMs < simTimeMs + durationMs, or undefined in a gap). If the serialized telemetry does not match the reconstructed bucket, the checkpoint's clock and telemetry are out of sync. Throwing prevents rendering telemetry that contradicts the restored timeline.

Solutions

  1. Re-capture the checkpoint so frame.telemetry and frame.timeMs are written atomically from the same tick.
  2. Update the checkpoint's frame.telemetry to match the tape bucket at bucketIndex (or null when in a gap).
  3. Migrate checkpoints saved by older versions to the current telemetry format before restore.
  4. Verify the tape used at restore is the same one the checkpoint was recorded against.

Example fix

// before: stale telemetry from a replaced bucket
c.frame.telemetry = oldBucket; // throws on restore
// after: recompute telemetry from the restored tape
const cand = world.tape[c.bucketIndex];
c.frame.telemetry = cand && c.frame.timeMs < cand.simTimeMs + cand.durationMs ? cand : undefined;
Defensive patterns

Strategy: validation

Validate before calling

function telemetryMatchesClock(c, tape) {
  const cand = tape[c.bucketIndex];
  const expected = cand && c.frame.timeMs < cand.simTimeMs + cand.durationMs ? cand : undefined;
  return JSON.stringify(c.frame.telemetry) === JSON.stringify(expected);
}

Type guard

const hasCoherentTelemetry = (c) => (c?.frame?.telemetry ?? undefined) !== undefined ? typeof c.frame.telemetry === 'object' : true;

Try / catch

try {
  world.resumeFromCheckpoint(c);
} catch (e) {
  if (e.message === 'Pet checkpoint telemetry does not match its clock.') {
    c.frame.telemetry = recomputeTelemetry(c, tape);
    world.resumeFromCheckpoint(c);
  } else throw e;
}

Prevention

When it happens

Trigger: Restoring a checkpoint whose frame.telemetry was captured against a different bucket than c.bucketIndex implies, or whose frame.timeMs sits in a gap but frame.telemetry is non-null (or vice versa) — a strict JSON deep-equality failure between c.frame.telemetry and the recomputed bucket.

Common situations: Older checkpoint format without telemetry field restored under new code; partial checkpoint writes; manually editing frame.timeMs or telemetry in a saved checkpoint; checkpoints exported before a telemetry bucket was replaced by acceptTelemetry.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/1d73c5938c88792b. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/pet_watch/pet-native.js:386

        const world = new PetWorld(points, tape, interactions, c.sim?.expressionVersion ?? 1, c.petCheckpointVersion === 2);
        if (c.petCheckpointVersion === 2) {
            world.hasTelemetry = c.hasTelemetry;
            world.origin = structuredClone(c);
        }
        if (c.history !== world.historyDigest()
            || c.bucketIndex >= 0 && world.tape[c.bucketIndex].simTimeMs > c.frame.timeMs + 1e-7
            // acceptTelemetry may fill past gaps after the most recent fixed tick.
            // Preserve that pending cursor exactly; it may lag only over empty gaps.
            || world.tape.some((b, i) => i > c.bucketIndex && b.simTimeMs <= c.frame.timeMs + 1e-7
                && (b.observed !== 0 || b.channel !== 'other' || b.errors || b.waiting || b.agentIds.length
                    || b.onsets.some(Boolean) || b.activeMs.some(Boolean)))
            || world.interactionLog.slice(0, c.interactionIndex).some(e => e.timeMs > c.frame.timeMs + 1e-7)
            || world.interactionLog[c.interactionIndex]?.timeMs <= c.frame.timeMs + 1e-7)
            throw new Error('Pet checkpoint does not match its recording.');
        const candidate = world.tape[c.bucketIndex];
        const telemetry = candidate && c.frame.timeMs < candidate.simTimeMs + candidate.durationMs ? candidate : undefined;
        if (JSON.stringify(c.frame.telemetry) !== JSON.stringify(telemetry))
            throw new Error('Pet checkpoint telemetry does not match its clock.');
        world.sim.restore(c.sim);
        world.score.restore(c.score);
        world.random.restore(c.random);
        world.accumulator = c.accumulator;
        world.tick = c.tick;
        world.bucketIndex = c.bucketIndex;
        world.interactionIndex = c.interactionIndex;
        world.branchTick = c.branchTick;
        world.behaviour = c.behaviour;
        world.until = c.until;
        world.targetX = c.targetX;
        world.targetY = c.targetY;
        world.x = c.x;
        world.y = c.y;
        world.flip = c.flip;
        world.lit = c.lit;
        world.lastActivity = c.lastActivity;
        world.addressedAt = c.addressedAt ?? -Infinity;

View on GitHub (pinned to 73e0f67d83)