{"record":{"id":"327832601efcfe6a","repo":"jdx/mise","slug":"cannot-save-reason","errorCode":null,"errorMessage":"cannot save: {reason}","messagePattern":"cannot save: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/save.rs","lineNumber":127,"sourceCode":"        draft.description = self.description.clone();\n        draft.description_source = Some(if trigger == Trigger::Agent {\n            DescriptionSource::Agent\n        } else {\n            DescriptionSource::User\n        });\n        draft.task = self.task.clone();\n        draft.labels = self.label.clone();\n        tokio::task::spawn_blocking(move || self.save_checkpoint(&store, &tracked, draft)).await?\n    }\n\n    fn capture(\n        &self,\n        store: &Store,\n        tracked: &crate::system::history::tracked::TrackedSet,\n        draft: Draft,\n    ) -> Result<()> {\n        if let Some(reason) = store.unavailable() {\n            bail!(\"cannot save: {reason}\");\n        }\n        // a save is a write: it waits for no running operation, refuses to\n        // interleave with one, and closes one that died\n        let _operation = crate::system::history::scope::take_operation_lock(store, tracked)?;\n        match store.attempt(tracked, draft)? {\n            Outcome::Created(entry) => {\n                info!(\n                    \"history: saved checkpoint {}: {}\",\n                    entry.id, entry.checkpoint.description\n                );\n                Ok(())\n            }\n            Outcome::Unchanged => {\n                info!(\"history: nothing changed since the latest checkpoint\");\n                Ok(())\n            }\n            Outcome::Unavailable(reason) => bail!(\"cannot save: {reason}\"),\n        }","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/dotfiles/save.rs#L109-L145","documentation":"The dotfiles checkpoint save aborts up front because the history Store reports itself unavailable via `store.unavailable()`. The store knows it cannot perform writes (e.g. storage backend broken, missing state directory, unsupported layout), so save refuses before taking the operation lock.","triggerScenarios":"Calling the save path (dotfiles save command -> capture -> save_checkpoint) when `Store::unavailable()` returns Some(reason): the history state store is in a state that forbids writes.","commonSituations":"State directory missing or on a read-only filesystem; history store schema too new/old; disk errors; history state corrupted by a previous crash.","solutions":["Read the `{reason}` suffix for the concrete cause and fix that (e.g. recreate the state dir)","Check mise's state directory permissions and free disk space","Run `mise doctor` to diagnose history store health","Disable/re-enable history or reset the dotfiles history store if corrupted"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"mise bootstrap dotfiles status >/dev/null 2>&1 || echo 'history store unavailable'","typeGuard":null,"tryCatchPattern":"if mise bootstrap dotfiles save 2>&1 | grep -q 'cannot save:'; then\n  echo \"history store unavailable: fix state dir before scripting saves\"\nfi","preventionTips":["Keep mise's state directory writable and on a healthy filesystem","Monitor free disk space where mise state lives","Recover interrupted history operations before scripted saves"],"tags":["cli","dotfiles","storage"],"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-14T05:17:10.506Z"}