{"record":{"id":"df02310851888dba","repo":"jdx/mise","slug":"cannot-merge-lockfile-version-from-into-lock","errorCode":null,"errorMessage":"cannot merge lockfile version {} from {} into lockfile version {} at {}; run `mise lock --upgrade` at the monorepo root","messagePattern":"cannot merge lockfile version (.+?) from (.+?) into lockfile version (.+?) at (.+?); run `mise lock --upgrade` at the monorepo root","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/lockfile.rs","lineNumber":1766,"sourceCode":"            Lockfile::read(target).unwrap_or_else(|err| handle_lockfile_read_error(err, target));\n        let subproject_lockfile = match Lockfile::read(source) {\n            Ok(lockfile) => lockfile,\n            Err(err) if is_not_found_report(&err) => continue,\n            Err(err) => return Err(err),\n        };\n        if !target_existed {\n            root_lockfile.lockfile_version = subproject_lockfile.lockfile_version;\n        } else if root_lockfile.lockfile_version != subproject_lockfile.lockfile_version\n            && allow_format_upgrade\n        {\n            // Keep the newer format so request bindings from either input remain\n            // serialized if the subsequent rebuild fails. Entries imported from\n            // version 0 remain reachable through the unbound-entry fallback.\n            root_lockfile.lockfile_version = root_lockfile\n                .lockfile_version\n                .max(subproject_lockfile.lockfile_version);\n        } else if root_lockfile.lockfile_version != subproject_lockfile.lockfile_version {\n            bail!(\n                \"cannot merge lockfile version {} from {} into lockfile version {} at {}; run `mise lock --upgrade` at the monorepo root\",\n                subproject_lockfile.lockfile_version,\n                display_path(source),\n                root_lockfile.lockfile_version,\n                display_path(target)\n            );\n        }\n        merge_lockfile_preserving_root(&mut root_lockfile, subproject_lockfile);\n        root_lockfile.save(target)?;\n        if let Err(err) = fs::remove_file(source)\n            && err.kind() != ErrorKind::NotFound\n        {\n            return Err(err.into());\n        }\n        migrated += 1;\n    }\n\n    if migrated > 0 {","sourceCodeStart":1748,"sourceCodeEnd":1784,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/lockfile.rs#L1748-L1784","documentation":"When merging a subproject lockfile into a monorepo root lockfile, mise requires both files to share the same lockfile_version (unless the subproject is legacy version 0, which is absorbed by raising the root's version). If the versions differ otherwise, the merge is refused with guidance to run `mise lock --upgrade` at the monorepo root.","triggerScenarios":"Running a build/operation that merges subproject mise.lock files into the root lockfile while the subproject was written with a different lockfile_version than the root — e.g. one part of the monorepo was locked by a newer mise. The error reports both versions and both file paths.","commonSituations":"Mixed mise versions across a monorepo; a partial `mise lock` upgrade touched only some subprojects; an older checkout or submodule lockfile committed at a different format version.","solutions":["Run `mise lock --upgrade` at the monorepo root, as the error instructs, to bring all lockfiles to the same version","Upgrade mise everywhere (CI, teammates) so all subprojects are relocked consistently, then commit the relocked files","Temporarily align by regenerating the offending subproject lockfile with the same mise version as the root"],"exampleFix":"# before: root lockfile_version = 2, subproject = 3\n# at monorepo root:\nmise lock --upgrade\ngit add mise.lock && git commit","handlingStrategy":"try-catch","validationCode":"// Before merging, check root and subproject lockfile versions match\nlet ver = |p: &str| -> u64 { toml::from_str::<toml::Value>(&std::fs::read_to_string(p).unwrap())\n    .unwrap().get(\"lockfile_version\").and_then(|v| v.as_integer()).unwrap_or(0) as u64 };\nassert_eq!(ver(\"mise.lock\"), ver(\"sub/mise.lock\"), \"run `mise lock --upgrade` at monorepo root\");","typeGuard":null,"tryCatchPattern":"match merge_lockfiles(root, sub) {\n    Err(e) if e.to_string().contains(\"cannot merge lockfile version\") => {\n        // follow the remediation the error suggests\n        upgrade_locks_at_root()?;\n        merge_lockfiles(root, sub)?;\n    }\n    other => other?,\n}","preventionTips":["Run `mise lock --upgrade` at the monorepo root after any mise upgrade","Keep one mise version across all subprojects and CI","Watch for lockfile_version drift in code review"],"tags":["lockfile","versioning","monorepo","merge"],"backgroundTag":"incompatible-source-type","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}