{"record":{"id":"68d8d75f3a5493cc","repo":"jdx/mise","slug":"unsupported-tool-purgatory-state-version-in","errorCode":null,"errorMessage":"unsupported tool purgatory state version {} in {}","messagePattern":"unsupported tool purgatory state version (.+?) in (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/tool_purgatory.rs","lineNumber":61,"sourceCode":"    Ok(SystemTime::now()\n        .duration_since(UNIX_EPOCH)\n        .wrap_err(\"system clock is before the Unix epoch\")?\n        .as_secs())\n}\n\nfn entry_key(path: &Path) -> String {\n    crate::hash::hash_sha256_to_str(&path.to_string_lossy())\n}\n\nfn load_state() -> Result<PurgatoryState> {\n    let path = state_path();\n    if !path.exists() {\n        return Ok(PurgatoryState::empty());\n    }\n    let state: PurgatoryState = serde_json::from_str(&crate::file::read_to_string(path)?)\n        .wrap_err_with(|| format!(\"failed to read tool purgatory state {}\", display_path(path)))?;\n    if state.schema_version != STATE_SCHEMA_VERSION {\n        bail!(\n            \"unsupported tool purgatory state version {} in {}\",\n            state.schema_version,\n            display_path(path)\n        );\n    }\n    Ok(state)\n}\n\nfn save_state(state: &PurgatoryState) -> Result<()> {\n    let path = state_path();\n    if state.entries.is_empty() {\n        match std::fs::remove_file(path) {\n            Ok(()) => {}\n            Err(err) if err.kind() == std::io::ErrorKind::NotFound => {}\n            Err(err) => return Err(err.into()),\n        }\n        return Ok(());\n    }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/tool_purgatory.rs#L43-L79","documentation":"Tool purgatory state is persisted as JSON with a schema_version field. load_state refuses any file written by a different schema version than the current STATE_SCHEMA_VERSION, because interpreting it could corrupt scheduling of removals or pruning.","triggerScenarios":"Calling scheduled_removals, schedule, forget_path, or auto_prune when the purgatory state file on disk was written by a newer or older mise build with a different STATE_SCHEMA_VERSION.","commonSituations":"Downgrading mise after the state schema changed; multiple mise versions (e.g. system vs dev build) sharing the same data directory; stale state surviving an upgrade.","solutions":["Delete the reported tool purgatory state file so it is recreated with the current schema","Ensure all mise installations on the machine are the same version","Re-run the purgatory operation after regenerating state (scheduled removals may need to be re-created)"],"exampleFix":"// before\nrm ~/.local/share/mise/tool-purgatory-state.json\n// after: mise recreates the file with the current schema on next schedule/auto_prune","handlingStrategy":"fallback","validationCode":"// check schema version before loading purgatory state\nconst st = JSON.parse(fs.readFileSync(path, 'utf8'));\nif (st.schema_version !== CURRENT) { fs.rmSync(path); console.warn('stale purgatory state removed'); }","typeGuard":null,"tryCatchPattern":"if let Err(e) = load_state(path) {\n    if e.to_string().contains(\"unsupported tool purgatory state version\") {\n        std::fs::remove_file(path).ok(); // regenerate with current schema\n    }\n}","preventionTips":["Keep a single mise version per machine/data directory","Clean state files after major mise upgrades","Avoid sharing mise data directories across versions"],"tags":["state","schema","purgatory","versioning"],"backgroundTag":"schema-validation-failed","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}