jdx/mise · error
matches more than one checkpoint; use a longer prefix
Error message
{spec:?} matches more than one checkpoint; use a longer prefix What it means
Prefix matching for checkpoint references can be ambiguous: if the given prefix matches more than one checkpoint UUID, mise cannot know which entry you mean and refuses to guess. The message asks for a longer prefix to disambiguate. This is the standard short-hash ambiguity error applied to checkpoint ids.
Solutions
- Repeat the command with a longer prefix until it is unique.
- List checkpoints to copy the full UUID.
- In scripts, always pass full ids captured from the list output instead of hand-shortened prefixes.
Example fix
// before mise dotfiles show ab Error: "ab" matches more than one checkpoint; use a longer prefix // after mise dotfiles show ab3f9c2e
Defensive patterns
Strategy: validation
Validate before calling
let matching: Vec<_> = entries.iter().filter(|e| e.checkpoint.uuid.starts_with(prefix)).collect();
if matching.len() > 1 {
eprintln!("prefix {prefix} is ambiguous ({} matches); use a longer prefix", matching.len());
} Type guard
fn prefix_is_unique(prefix: &str, entries: &[Entry]) -> bool {
entries.iter().filter(|e| e.checkpoint.uuid.starts_with(prefix)).count() == 1
} Prevention
- Use full UUIDs in scripts and aliases.
- Grow prefixes until unique before running the command.
- Prefer interactive/picker flows when history is large.
When it happens
Trigger: Supplying a short UUID prefix that is a prefix of two or more stored checkpoint UUIDs, e.g. `mise dotfiles show abc` when both `abc1...` and `abc9...` exist.
Common situations: Using a 1-3 character prefix from memory; large history where early characters collide; scripting with truncated ids.
Related errors
- invalid checkpoint reference
- no history checkpoint matches
- appeared after was protected; nothing more was changed
- cannot retain an unreadable plaintext version of newly…
- cannot set up from a setup repository
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/3ce8702dbf41316d.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/history/store.rs:1019
return entries
.iter()
.find(|entry| entry.id == id)
.map(|entry| entry.id)
.ok_or_else(|| eyre!("no history checkpoint matches {spec:?}"));
} else {
spec
};
if prefix.is_empty() {
bail!("invalid checkpoint reference {spec:?}");
}
let matches: Vec<&Entry> = entries
.iter()
.filter(|entry| entry.checkpoint.uuid.starts_with(prefix))
.collect();
match matches.as_slice() {
[one] => Ok(one.id),
[] => bail!("no history checkpoint matches {spec:?}"),
_ => bail!("{spec:?} matches more than one checkpoint; use a longer prefix"),
}
}
pub(crate) fn now_rfc3339() -> String {
chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Millis, true)
}
pub(crate) fn new_uuid() -> String {
uuid::Uuid::now_v7().to_string()
}
pub(crate) fn write_json<T: Serialize>(path: &Path, value: &T) -> Result<()> {
let mut text = serde_json::to_string_pretty(value)?;
text.push('\n');
if let Some(parent) = path.parent() {
file::create_dir_all(parent)?;
}
file::write_atomic(path, text).wrap_err_with(|| format!("writing {}", display_path(path)))?;View on GitHub (pinned to 533346cc37)