jdx/mise · error
history is disabled (history.enabled = false)
Error message
history is disabled (history.enabled = false)
What it means
Dotfile checkpoint saving requires the history subsystem to be enabled via the history.enabled setting. When the setting is false, save refuses to run because checkpoints could not be recorded. This is an explicit opt-out guard, not a malfunction.
Solutions
- Enable history: run `mise settings set history.enabled true` or set it in the active config
- If history should stay disabled, do not use dot save; manage dotfiles manually
Example fix
# before (~/.config/mise/config.toml) [history] enabled = false # after [history] enabled = true
Defensive patterns
Strategy: validation
Validate before calling
enabled=$(mise settings get history.enabled)
[ "$enabled" = "true" ] || { echo "history disabled"; exit 1; } Try / catch
if ! mise dot save update 2>err.log; then grep -q 'history is disabled' err.log && mise settings set history.enabled true fi
Prevention
- Keep history.enabled true on machines that use dot commands
- Document the dependency of dot save/sync/track --encrypt on history
- Check settings after applying shared configs
When it happens
Trigger: Running any `mise dot save ...` while `history.enabled = false` in mise settings (settings.toml, config, or MISE_ env override).
Common situations: Users who disabled dotfile history earlier and forgot; shared config files with history disabled; CI environments where history is disabled by default policy.
Related errors
- dotfiles: cannot enroll encrypted paths while history is…
- history is disabled (history.enabled = false)
- failed to add
- is not managed by [dotfiles]
- a glob is required
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/dac1dc32e00f90b2.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/dotfiles/save.rs:73
match self.capture(store, tracked, draft) {
Ok(()) => Ok(()),
Err(err) if self.best_effort => {
warn!("history save: {err:#}");
Ok(())
}
Err(err) => Err(err),
}
}
async fn save(self) -> Result<()> {
let trigger = match self.trigger.as_str() {
"save" => Trigger::Save,
"agent" => Trigger::Agent,
"update" => Trigger::Update,
other => bail!("unknown trigger {other:?}; use save, agent, or update"),
};
if !crate::config::Settings::get().history.enabled {
bail!("history is disabled (history.enabled = false)");
}
let (store, tracked, entries) = super::history::open().await?;
if !self.paths.is_empty() {
let walk = tracked.walk()?;
for path in &self.paths {
let path = normalize_target(path);
let captured = walk.files.keys().any(|file| file.starts_with(&path));
if !captured {
// saving a deleted manual-save path saves the deletion,
// provided the path was captured before (a path that
// never existed is not a deletion)
let deletion = tracked
.entry_for(&path)
.is_some_and(|entry| !entry.policy.autosave)
&& std::fs::symlink_metadata(&path)
.is_err_and(|err| err.kind() == std::io::ErrorKind::NotFound)
&& previously_captured(&store, &entries, &path)?;
if deletion {View on GitHub (pinned to 533346cc37)