jdx/mise · error

unsupported tool purgatory state version {} in {}

Error message

unsupported tool purgatory state version {} in {}

What it means

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.

Source

Thrown at src/tool_purgatory.rs:61

    Ok(SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .wrap_err("system clock is before the Unix epoch")?
        .as_secs())
}

fn entry_key(path: &Path) -> String {
    crate::hash::hash_sha256_to_str(&path.to_string_lossy())
}

fn load_state() -> Result<PurgatoryState> {
    let path = state_path();
    if !path.exists() {
        return Ok(PurgatoryState::empty());
    }
    let state: PurgatoryState = serde_json::from_str(&crate::file::read_to_string(path)?)
        .wrap_err_with(|| format!("failed to read tool purgatory state {}", display_path(path)))?;
    if state.schema_version != STATE_SCHEMA_VERSION {
        bail!(
            "unsupported tool purgatory state version {} in {}",
            state.schema_version,
            display_path(path)
        );
    }
    Ok(state)
}

fn save_state(state: &PurgatoryState) -> Result<()> {
    let path = state_path();
    if state.entries.is_empty() {
        match std::fs::remove_file(path) {
            Ok(()) => {}
            Err(err) if err.kind() == std::io::ErrorKind::NotFound => {}
            Err(err) => return Err(err.into()),
        }
        return Ok(());
    }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Delete the reported tool purgatory state file so it is recreated with the current schema
  2. Ensure all mise installations on the machine are the same version
  3. Re-run the purgatory operation after regenerating state (scheduled removals may need to be re-created)

Example fix

// before
rm ~/.local/share/mise/tool-purgatory-state.json
// after: mise recreates the file with the current schema on next schedule/auto_prune
Defensive patterns

Strategy: fallback

Validate before calling

// check schema version before loading purgatory state
const st = JSON.parse(fs.readFileSync(path, 'utf8'));
if (st.schema_version !== CURRENT) { fs.rmSync(path); console.warn('stale purgatory state removed'); }

Try / catch

if let Err(e) = load_state(path) {
    if e.to_string().contains("unsupported tool purgatory state version") {
        std::fs::remove_file(path).ok(); // regenerate with current schema
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/68d8d75f3a5493cc. Report an issue: GitHub.