{"record":{"id":"f4a0b67a5bc76caa","repo":"jdx/mise","slug":"unsupported-lockfile-format","errorCode":null,"errorMessage":"unsupported lockfile format {}","messagePattern":"unsupported lockfile format (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lockfile.rs","lineNumber":3466,"sourceCode":"                }\n                // Silently discard env field from old lockfiles for backwards compat\n                t.remove(\"env\");\n                LockfileTool {\n                    version: t\n                        .remove(\"version\")\n                        .map(|v| v.try_into())\n                        .transpose()?\n                        .unwrap_or_default(),\n                    backend: t\n                        .remove(\"backend\")\n                        .map(|v| v.try_into())\n                        .transpose()?\n                        .unwrap_or_default(),\n                    options,\n                    platforms,\n                }\n            }\n            _ => bail!(\"unsupported lockfile format {}\", value),\n        };\n        Ok(tool)\n    }\n}\n\nimpl LockfileTool {\n    fn into_toml_value(self) -> toml::Value {\n        let mut table = toml::Table::new();\n        table.insert(\"version\".to_string(), self.version.into());\n        if let Some(backend) = self.backend {\n            table.insert(\"backend\".to_string(), backend.into());\n        }\n        if !self.options.is_empty() {\n            let opts_table: toml::Table = self\n                .options\n                .into_iter()\n                .map(|(k, v)| (k, toml::Value::String(v)))\n                .collect();","sourceCodeStart":3448,"sourceCodeEnd":3484,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/lockfile.rs#L3448-L3484","documentation":"Each element of a tools.<short> array in mise.lock must itself be a table (parsed for version, backend, options, platforms keys at src/lockfile.rs:3445-3467). A non-table element — e.g. a bare version string inside the array — bails with \"unsupported lockfile format {}\".","triggerScenarios":"tools.node = [\"22.0.0\"] — an array of strings instead of an array of tables — from hand edits or a lockfile written by a different (older or newer) mise format.","commonSituations":"Hand-simplifying lockfile entries; lockfiles from format transitions between mise versions; bad merge resolutions.","solutions":["Regenerate the lockfile: rm mise.lock && mise lock.","Align mise versions between the machine that wrote the lockfile and the one reading it.","Never hand-edit [[tools.<name>]] entries."],"exampleFix":"# before (mise.lock)\n[[tools.node]]\n# entry accidentally replaced by: tools.node = [\"22.0.0\"]\n\n# after — regenerate\n$ rm mise.lock && mise lock","handlingStrategy":"validation","validationCode":"# CI guard: each tools.<short> element must be a table\npython3 -c \"\nimport tomllib\nfor name, entries in tomllib.load(open('mise.lock', 'rb')).get('tools', {}).items():\n    for e in entries:\n        if not isinstance(e, dict):\n            raise SystemExit('tools.%s entry must be a table, got %r' % (name, e))\n\"","typeGuard":null,"tryCatchPattern":"\"unsupported lockfile format …\" on a tools entry means the element type is wrong (e.g. bare string in the array): rm mise.lock && mise lock with an aligned mise version. Treat it as generated-output corruption — regeneration, not repair.","preventionTips":["Never hand-simplify lockfile entries to bare version strings.","Regenerate lockfiles after version bumps and bad merges.","Run a TOML shape assertion on mise.lock in CI before mise install."],"tags":["lockfile","parse","toml","structure"],"backgroundTag":"invalid-lockfile-format","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}