{"record":{"id":"e7182ef2bb1b9f39","repo":"Hmbown/CodeWhale","slug":"shared-habitat-could-not-restore-its-file-was-kept","errorCode":null,"errorMessage":"Shared habitat could not restore; its file was kept","messagePattern":"Shared habitat could not restore; its file was kept","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/owner.rs","lineNumber":445,"sourceCode":"                .map(|line| {\n                    line.split_whitespace()\n                        .filter_map(|n| n.parse().ok())\n                        .collect()\n                })\n                .collect();\n            ctx.globals()\n                .set(\"points\", serde_json::to_string(&points).unwrap())?;\n            ctx.eval::<(), _>(include_bytes!(\"pet-native.js\").as_slice())?;\n            ctx.eval::<(), _>(\"globalThis.pet = new PetNative(points, '', '[]', true)\")?;\n            if !saved.recording.is_null() {\n                ctx.globals().set(\"saved\", saved.recording.to_string())?;\n                ctx.eval::<(), _>(\n                    \"pet.restoreRecording(saved); pet.resumeEngine(); delete globalThis.saved\",\n                )?;\n            }\n            Ok(())\n        })\n        .map_err(|_| anyhow::anyhow!(\"Shared habitat could not restore; its file was kept\"))?;\n    let mut producer: Option<(String, u64, Instant, String)> = None;\n    let mut audio: Option<(String, Instant)> = None;\n    let mut playback: Option<(super::audio::Output, super::audio_cursor::AudioCursor)> = None;\n    let mut audio_error = false;\n    let mut waiting = false;\n    let mut last_save = Instant::now();\n    let mut storage_error = false;\n    let origin = Instant::now();\n    let initial_time: f64 = context.with(|ctx| ctx.eval(\"JSON.parse(pet.snapshot()).timeMs\"))?;\n    let mut last = origin;\n    let mut ticks = 0u64;\n    let mut measurements = VecDeque::<f64>::new();\n    save(&context, &mut saved, &mut store)?;\n    let _ = ready.send(Ok(()));\n    loop {\n        *deadline\n            .lock()\n            .map_err(|_| anyhow::anyhow!(\"Clock lock failed\"))? =","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/owner.rs#L427-L463","documentation":"During startup the shared habitat's saved state is loaded into the JS runtime and restored via pet.restoreRecording(saved). If that eval fails for any reason, run_world() maps the whole closure error to this message, indicating the saved state file was intentionally kept (not deleted) so restoration can be retried later.","triggerScenarios":"ctx.eval of the restore script fails — e.g. the saved JSON deserialized but does not match what pet.restoreRecording expects (corrupt or schema-drifted save), the JS engine errored, or saved was absent/malformed despite passing the earlier version/uuid checks.","commonSituations":"A save written by a newer Codewhale version with a changed recording format; truncated or hand-edited habitat state file; JS runtime failure mid-restore after an earlier crash.","solutions":["Inspect the kept habitat save file for schema drift or corruption and repair or remove it (it is preserved precisely so you can decide)","Downgrade/upgrade Codewhale so the runtime's restoreRecording matches the save's format","Reproduce with verbose JS error output — the anyhow mapping discards the underlying cause, so check logs for the original eval error"],"exampleFix":"// before\n.map_err(|_| anyhow::anyhow!(\"Shared habitat could not restore; its file was kept\"))?;\n// after\n.map_err(|e| anyhow::anyhow!(\"Shared habitat could not restore; its file was kept: {e}\"))?;","handlingStrategy":"validation","validationCode":"// Validate the save before attempting restore\nfn save_is_loadable(text: &str) -> bool {\n    serde_json::from_str::<Saved>(text)\n        .map(|v| v.version == 1 && uuid::Uuid::parse_str(&v.identity).is_ok())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match run_world(&root) {\n    Err(e) if e.to_string().contains(\"could not restore\") => {\n        // save file was kept; quarantine or repair it, then retry\n        archive_save_and_start_fresh(&root)?;\n    }\n    r => r?,\n}","preventionTips":["Never hand-edit the habitat save file; keep schema migrations forward-compatible","Back up the save before upgrading Codewhale versions","Watch for eval errors at restore time in logs — the mapped error hides the root cause"],"tags":["state-restore","javascript-runtime","saved-state","data-corruption"],"backgroundTag":"schema-validation-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}