jdx/mise · error
another history operation is running
Error message
another history operation is running
What it means
Same lock-acquisition path as the parameterized variant: when the deadline expires and store::read_marker_in finds no marker, acquire_operation_lock bails with the generic 'another history operation is running'. The lockfile is held but no marker was recorded.
Solutions
- Confirm no mise history process is alive (ps), then delete the stale lockfile in MISE_STATE_DIR and retry
- Re-run the operation after ensuring only one mise instance runs
- If crashes recur, check for SIGKILL/OOM during history operations
Example fix
// before: stale lock ps aux | grep mise # confirm nothing running rm "$(mise state-dir)/history.lock" // after: remove stale lock, retry
Defensive patterns
Strategy: retry
Validate before calling
if history.operation_lock_held() && !history.operation_marker_exists() {
eprintln!("stale lock without marker; safe to clear after confirming no mise process");
} Try / catch
match history.take_operation_lock() {
Err(e) if e.to_string() == "another history operation is running" => {
if !history.any_mise_process_alive() {
history.clear_stale_lock()?;
history.take_operation_lock()?;
}
}
other => other?,
} Prevention
- Confirm no mise processes are alive before removing lockfiles
- Prefer graceful termination (SIGTERM) so markers get written
- Monitor for OOM kills that leave locks without markers
When it happens
Trigger: take_operation_lock_with_wait / recovery_lock timed out on a held LockFile::at(path) while no marker exists in the state dir — e.g. the holder crashed after locking but before writing its marker, or the marker file was deleted.
Common situations: Stale lockfile from a killed mise process; a holder that locked but died before writing the marker; racing processes on a shared MISE_STATE_DIR.
Related errors
- another history operation is running
- appeared after was protected; nothing more was changed
- changed after it was protected; nothing more was changed
- history changed during the operation; cannot replace its…
- incoming application requires an active recovery operation
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/b61407e313a05f5d.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/scope.rs:725
let path = store::operation_lock_in(state_dir);
// a running operation (the watcher applying incoming changes, say) is
// usually over in moments: wait for it a bounded while before failing
let deadline = std::time::Instant::now() + wait;
let mut announced = false;
let lock = loop {
if let Some(lock) = LockFile::at(&path).try_lock()? {
break lock;
}
let marker = store::read_marker_in(state_dir)?;
if std::time::Instant::now() >= deadline {
match marker {
Some(marker) => bail!(
"another history operation is running: {} since {} ({})",
marker.kind.as_str(),
marker.started_at,
marker.command
),
None => bail!("another history operation is running"),
}
}
if !announced {
announced = true;
info!(
"history: waiting for another history operation to finish{}",
marker
.map(|marker| format!(": {} ({})", marker.kind.as_str(), marker.command))
.unwrap_or_default()
);
}
std::thread::sleep(OPERATION_LOCK_POLL);
};
Ok(lock)
}
/// How long an operation waits for a running one, and how often it looks.
const OPERATION_LOCK_WAIT: std::time::Duration = std::time::Duration::from_secs(30);View on GitHub (pinned to 533346cc37)