{"record":{"id":"c0a54b10b93a3fe7","repo":"jdx/mise","slug":"invalid-checkpoint-reference-spec","errorCode":null,"errorMessage":"invalid checkpoint reference {spec:?}","messagePattern":"invalid checkpoint reference (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/store.rs","lineNumber":1010,"sourceCode":"                )\n            });\n    }\n    let prefix = if let Some(prefix) = spec.strip_prefix(\"commit:\") {\n        prefix\n    } else if !spec.is_empty() && spec.bytes().all(|byte| byte.is_ascii_digit()) {\n        let id = spec.parse::<u64>().map_err(|_| {\n            eyre!(\"invalid checkpoint ID {spec:?}; use commit:<sha> for a numeric commit hash\")\n        })?;\n        return entries\n            .iter()\n            .find(|entry| entry.id == id)\n            .map(|entry| entry.id)\n            .ok_or_else(|| eyre!(\"no history checkpoint matches {spec:?}\"));\n    } else {\n        spec\n    };\n    if prefix.is_empty() {\n        bail!(\"invalid checkpoint reference {spec:?}\");\n    }\n    let matches: Vec<&Entry> = entries\n        .iter()\n        .filter(|entry| entry.checkpoint.uuid.starts_with(prefix))\n        .collect();\n    match matches.as_slice() {\n        [one] => Ok(one.id),\n        [] => bail!(\"no history checkpoint matches {spec:?}\"),\n        _ => bail!(\"{spec:?} matches more than one checkpoint; use a longer prefix\"),\n    }\n}\n\npub(crate) fn now_rfc3339() -> String {\n    chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Millis, true)\n}\n\npub(crate) fn new_uuid() -> String {\n    uuid::Uuid::now_v7().to_string()","sourceCodeStart":992,"sourceCodeEnd":1028,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/store.rs#L992-L1028","documentation":"When resolving a checkpoint reference, mise first tries to expand a spec to a UUID prefix and then match entries. If after expansion the prefix is empty, there is nothing sensible to match against, so mise rejects the spec as invalid rather than matching every entry. This is an input-validation error for checkpoint selectors.","triggerScenarios":"Passing an empty or whitespace-only checkpoint spec (after the non-UUID branch), or a spec that fails the expansion logic leaving an empty prefix, e.g. `mise dotfiles checkout \"\"`.","commonSituations":"A shell variable holding the checkpoint id is unset/empty (`$LATEST` empty); quoting mistake passes an empty argument; script automation drops the id.","solutions":["Supply a non-empty checkpoint id or UUID prefix.","List available checkpoints to copy a valid id.","Check shell scripts for unset variables feeding the empty spec.","Quote arguments to avoid the shell stripping them."],"exampleFix":"// before\nmise dotfiles checkout \"$CKPT\"   # CKPT is unset\nError: invalid checkpoint reference \"\"\n\n// after\nCKPT=$(mise dotfiles history list --latest-id)\nmise dotfiles checkout \"$CKPT\"","handlingStrategy":"validation","validationCode":"if spec.trim().is_empty() {\n  eprintln!(\"checkpoint reference is empty; run `mise dotfiles history list` for valid ids\");\n}","typeGuard":"fn is_valid_checkpoint_spec(spec: &str) -> bool {\n  !spec.trim().is_empty()\n}","tryCatchPattern":null,"preventionTips":["Never pass possibly-unset shell variables unquoted into checkpoint commands.","Default empty specs to 'latest' or an interactive picker in scripts.","Validate arguments in wrapper scripts before calling mise."],"tags":["cli","history","checkpoint","validation"],"backgroundTag":"invalid-argument-value","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"}