{"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":294,"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":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/lock.rs#L276-L312","documentation":"When `mise lock` finishes (or rolls back), it restores snapshotted lockfile contents; any per-file restore failures are collected and joined into a single error via `bail!(\"{}\", errors.join(\"\\n\"))`. This error surfaces one or more underlying restore failures (I/O, permissions, missing files) that prevented returning the filesystem to its pre-command state.","triggerScenarios":"`restore_lockfile_snapshots` fails to write back original lockfile content for one or more paths — e.g. read-only filesystem, file deleted by another process, permission change — during normal completion or rollback (as in the rollback tests referenced).","commonSituations":"Lockfile made read-only by git or filesystem permissions; disk full; another process deleting the lockfile mid-run; rollback after a mid-command failure.","solutions":["Read the joined messages to identify which files failed to restore","Fix permissions on the listed lockfiles (chmod/chown) and re-run the command","Check disk space and that the lockfiles still exist; restore from git if contents were lost (`git checkout -- mise.lock`)"],"exampleFix":"// before\nchmod 444 mise.lock\n// after\nchmod 644 mise.lock\nmise lock","handlingStrategy":"try-catch","validationCode":"// bash: ensure lockfiles are writable before locking\nfor f in mise.lock; do [[ -w \"$f\" ]] || chmod u+w \"$f\"; done","typeGuard":null,"tryCatchPattern":"// bash\nif ! mise lock; then git checkout -- mise.lock; mise lock; fi","preventionTips":["Keep lockfiles writable by the user running mise","Ensure adequate disk space","Don't delete lockfiles while mise commands run"],"tags":["lockfile","file-write","restore","atomicity"],"backgroundTag":"file-write-failed","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}