jdx/mise · error

unsupported lockfile format {value}

Error message

unsupported lockfile format {value}

What it means

LockfileTool::try_from(toml::Value) accepts only the known lockfile tool entry shapes (a table with version/specifiers/options/platforms fields, or the recognized legacy shape); any other TOML value type bails with 'unsupported lockfile format <value>'. It is the per-tool structural guard during parsing.

Source

Thrown at src/lockfile.rs:4017

                // Silently discard env field from old lockfiles for backwards compat
                t.remove("env");
                LockfileTool {
                    version: t
                        .remove("version")
                        .map(|v| v.try_into())
                        .transpose()?
                        .unwrap_or_default(),
                    backend: t
                        .remove("backend")
                        .map(|v| v.try_into())
                        .transpose()?
                        .unwrap_or_default(),
                    specifiers,
                    options,
                    platforms,
                }
            }
            _ => bail!("unsupported lockfile format {}", value),
        };
        Ok(tool)
    }
}

impl LockfileTool {
    fn into_toml_value(self, include_specifiers: bool) -> toml::Value {
        let mut table = toml::Table::new();
        table.insert("version".to_string(), self.version.into());
        if let Some(backend) = self.backend {
            table.insert("backend".to_string(), backend.into());
        }
        if include_specifiers && !self.specifiers.is_empty() {
            table.insert(
                "specifiers".to_string(),
                self.specifiers.into_iter().collect::<Vec<_>>().into(),
            );
        }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Rewrite each tool entry as a proper table with version (and optional specifiers/options/platforms) fields
  2. Delete mise.lock and regenerate it with `mise lock` / `mise install` using the current mise version
  3. Diff mise.lock against a known-good version (git checkout -- mise.lock then re-lock) to restore the expected format

Example fix

# before (mise.lock)
[[tools.node]]
"20.0.0"
# after
[[tools.node]]
version = "20.0.0"
Defensive patterns

Strategy: validation

Validate before calling

// Validate each tool entry is a supported table shape before parsing
for e in tools_array {
    assert!(e.is_table() && e.get("version").map(|v| v.is_str()).unwrap_or(false),
            "tool entry must be a table with string version");
}

Type guard

fn is_lockfile_tool(v: &toml::Value) -> bool {
    v.as_table().map(|t| t.get("version").map(|x| x.is_str()).unwrap_or(false)).unwrap_or(false)
}

Prevention

When it happens

Trigger: Parsing a [[tools.<short>]] entry whose value is not one of the supported shapes — e.g. a bare string version, an integer, or a table missing the required structure. Comes from hand-edited lockfiles, foreign writers, or corrupted merges.

Common situations: Hand-writing mise.lock tool entries as strings; a script generating lockfile entries incorrectly; merge conflicts leaving mixed/malformed tool blocks.

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/26a9f5fb7d0d3bc8. Report an issue: GitHub.