{"record":{"id":"679c0868a834e4a2","repo":"jdx/mise","slug":"error-679c08","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/lock.rs","lineNumber":252,"sourceCode":"    let mut errors = Vec::new();\n    for rollback in rollbacks.into_iter().rev() {\n        let result = match rollback.replacement {\n            Some(replacement) => replacement.commit(),\n            None => match fs::remove_file(&rollback.path) {\n                Ok(()) => Ok(()),\n                Err(err) if err.kind() == ErrorKind::NotFound => Ok(()),\n                Err(err) => Err(err.into()),\n            },\n        };\n        if let Err(err) = result {\n            errors.push(format!(\"{}: {err:?}\", display_path(&rollback.path)));\n        }\n    }\n    lockfile::invalidate_caches();\n    if errors.is_empty() {\n        Ok(())\n    } else {\n        bail!(\"{}\", errors.join(\"\\n\"))\n    }\n}\n\n#[derive(Debug, Eq, PartialEq)]\nenum LockTaskStatus {\n    Updated,\n    Unresolved,\n    Failed,\n    ProvenanceFailed,\n}\n\nfn classify_lock_result(\n    resolution_error: Option<String>,\n    error_is_fatal: bool,\n    applied: bool,\n) -> (LockTaskStatus, Option<String>) {\n    if let Some(error) = resolution_error.filter(|_| error_is_fatal) {\n        (LockTaskStatus::Failed, Some(error))","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/lock.rs#L234-L270","documentation":"`mise lock` restores per-tool lockfile snapshot entries; each failed restore is collected and, if any errors occurred, they are joined with newlines and raised as a single bail. The message content is whatever the individual restore failures reported, so this error surfaces aggregate lockfile-restore failures after all tasks have run.","triggerScenarios":"Running `mise lock` (restore_lockfile_snapshots, invoked from run and rollback paths) when one or more snapshot restore operations fail — e.g. a snapshot file cannot be written or a replaced file cannot be restored — so errors is non-empty at the end of the function.","commonSituations":"Read-only filesystems or permission problems preventing snapshot writes during `mise lock`; concurrent mise processes locking the same config files; rollback paths after partially failed lock operations.","solutions":["Read the joined error lines in the message — each line identifies the specific restore failure; fix those individually.","Check write permissions on the mise config directory and lockfiles, and close editors/programs holding the files open.","Ensure no other mise process is running concurrently (stale locks), then rerun `mise lock`.","Restore the affected config files from version control if snapshots are corrupt, and rerun."],"exampleFix":"// diagnose: rerun with debug to see the per-file failures\nMISE_DEBUG=1 mise lock\n// after fixing permission/lock issues\nmise lock","handlingStrategy":"retry","validationCode":"# shell: check writable config dir before locking\n[ -w \"$(dirname \"$(mise where 2>/dev/null || echo ~/.config/mise)/..\")\" ] || chmod -R u+w ~/.config/mise\nmise lock","typeGuard":null,"tryCatchPattern":"# shell: inspect joined error lines, fix, then retry\nif ! mise lock; then\n  MISE_DEBUG=1 mise lock 2>lock.err || true\n  cat lock.err   # each line is one restore failure\n  # fix permissions/close editors, then:\n  mise lock\nfi","preventionTips":["Ensure mise config directories are writable before running `mise lock`.","Avoid concurrent mise processes operating on the same config files.","Keep lockfiles under version control so failed restores can be recovered."],"tags":["cli","lockfile","aggregate-errors","file-write"],"backgroundTag":"file-write-failed","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"}