{"record":{"id":"b9610f9662b416b4","repo":"Hmbown/CodeWhale","slug":"unsupported-pet-expression-version-world","errorCode":null,"errorMessage":"Unsupported pet expression version.","messagePattern":"Unsupported pet expression version\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/src/core/pet-world.ts","lineNumber":140,"sourceCode":"      waitSince: this.waitSince, food: this.food, members: [...this.members.values()], lastStill: this.lastStill,\n      frame: this.frame, voices: this.voices });\n  }\n\n  recording(withCheckpoint = true, completed = false): PetRecording {\n    const tapeEnd = completed ? this.bucketIndex + 1 : this.tapeLog.length;\n    const inputEnd = completed ? this.interactionIndex : this.interactionLog.length;\n    const history = this.historyDigest(tapeEnd, inputEnd);\n    return { petReplayVersion: this.segmented ? 2 : 1, expressionVersion: this.sim.expressionVersion,\n      tape: this.tapeLog.slice(0, tapeEnd), interactions: this.interactionLog.slice(0, inputEnd).map(e => ({ ...e })),\n      ...(this.origin ? { start: { ...structuredClone(this.origin), hasTelemetry: this.hasTelemetry, history } } : {}),\n      ...(withCheckpoint ? { checkpoint: { ...this.checkpoint(), history } } : {}) };\n  }\n\n  static fromRecording(points: [number, number][], value: unknown): PetWorld {\n    const r = value as PetRecording;\n    if (!r || ![1, 2].includes(r.petReplayVersion) || !Array.isArray(r.tape) || !Array.isArray(r.interactions)) throw new Error('Invalid pet recording.');\n    const version = r.expressionVersion === undefined ? 1 : r.expressionVersion;\n    if (![1, 2].includes(version)) throw new Error('Unsupported pet expression version.');\n    if (r.checkpoint !== undefined && !r.checkpoint || r.start !== undefined && !r.start) throw new Error('Invalid pet checkpoint.');\n    for (const c of [r.start, r.checkpoint]) if (c && (c.sim?.expressionVersion ?? 1) !== version) throw new Error('Pet expression version does not match its checkpoint.');\n    if (r.petReplayVersion === 1 && (r.start || r.checkpoint && r.checkpoint.petCheckpointVersion !== 1)) throw new Error('Invalid legacy pet recording.');\n    if (r.petReplayVersion === 2 && (!r.start || r.start.petCheckpointVersion !== 2 || r.start.historyStart !== r.start.tick)) throw new Error('The recording segment is missing its starting checkpoint.');\n    const first = r.start && PetWorld.restore(points, r.tape, r.interactions, r.start);\n    const world = r.checkpoint ? PetWorld.restore(points, r.tape, r.interactions, r.checkpoint) : first ?? new PetWorld(points, r.tape, r.interactions, version);\n    if (first) {\n      if (!world.segmented || world.tick < first.tick || r.checkpoint && r.checkpoint.historyStart !== first.tick) throw new Error('Pet segment checkpoints do not agree.');\n      world.origin = first.checkpoint();\n    }\n    return world;\n  }\n\n  /** Retire only consumed input. The exact origin makes each archived segment\n   * independently replayable; no particle, random stream or score is reset. */\n  prepareSegment(): PetSegment {\n    const dropTape = Math.max(0, this.bucketIndex), dropInputs = this.interactionIndex, previous = this.origin;\n    const tape = this.tapeLog.slice(dropTape), interactions = this.interactionLog.slice(dropInputs);","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/src/core/pet-world.ts#L122-L158","documentation":"Thrown by PetWorld.fromRecording when the recording's expressionVersion is not one this build understands. Recordings persist the simulator's expressionVersion; a recording produced by a newer (or unknown) simulator cannot be replayed faithfully, so restoring is refused instead of misinterpreting expression state.","triggerScenarios":"Loading a recording whose expressionVersion is 0, 3, or any value other than 1/2 (undefined is allowed and means 1).","commonSituations":"Downgrading the app and opening recordings made by a newer version; hand-edited recording files; a corrupt expressionVersion field.","solutions":["Upgrade the app/library to a version supporting the recording's expressionVersion.","Re-record or re-export the pet with a supported expression version (1 or 2).","Fix or remove the corrupted expressionVersion field if the file was hand-edited."],"exampleFix":"// before\nconst world = PetWorld.fromRecording(points, newRecordingFromFutureVersion);\n// after\nif (![1, 2].includes(newRecordingFromFutureVersion.expressionVersion)) {\n  throw new Error('Upgrade the app to load this recording.');\n}\nconst world = PetWorld.fromRecording(points, newRecordingFromFutureVersion);","handlingStrategy":"validation","validationCode":"const version = rec.expressionVersion ?? 1;\nif (![1,2].includes(version)) throw new Error('expressionVersion ' + version + ' not supported; upgrade the app');","typeGuard":null,"tryCatchPattern":"try { PetWorld.fromRecording(points, rec); } catch (e) { if (e.message.includes('expression version')) promptUpgrade(); }","preventionTips":["Persist expressionVersion with recordings and check it at load time.","On app downgrade, refuse or migrate recordings rather than loading blindly."],"tags":["versioning","compatibility"],"backgroundTag":"unsupported-enum-value","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}