jdx/mise · error
invalid completion cache identity
Error message
invalid completion cache identity
What it means
completion_cache_path builds the on-disk path where a generated completion script is cached (resources/completions-v2/<bin>/<shell>.completion). Before building it, it validates that both the binary name and the shell name are plain file names (no path separators, '..', etc.). If either contains path-like or unsafe characters, mise refuses to construct the cache path to prevent path traversal or corrupt cache layout.
Source
Thrown at src/packslip.rs:1134
/// The `shell` completion script for `tool`, from the packslip of the
/// version that is active right now.
fn completion_bin<'a>(statement: &'a Statement, tool: Option<&'a str>) -> Option<&'a str> {
tool.map(packslip::command_name)
.filter(|name| {
statement
.predicate
.artifacts
.iter()
.flat_map(|a| &a.bin)
.any(|b| b.name == *name)
})
.or_else(|| statement.sole_bin())
}
fn completion_cache_path(install_path: &Path, tool: &str, shell: &str) -> Result<PathBuf> {
let bin = packslip::command_name(tool);
if !file::is_plain_file_name(bin) || !file::is_plain_file_name(shell) {
bail!("invalid completion cache identity");
}
Ok(install_path
.join(RESOURCES_DIR)
.join("completions-v2")
.join(bin)
.join(format!("{shell}.completion")))
}
pub(crate) async fn completion_script(
config: &Arc<Config>,
tool: &str,
shell: &str,
) -> Result<String> {
let ts = config.get_toolset().await?;
let (backend, tv) = find_tool(config, ts, tool).await?;
let install_path = tv.install_path();
let Some(statement) = statement(&install_path)? else {
bail!(View on GitHub (pinned to afd2eddd3a)
Solutions
- Use a plain tool/command name (no '/', '..', or separators) in `mise completion <shell> --tool <name>`.
- Pass a supported shell name exactly: bash, zsh, fish, or pwsh.
- If a packslip declares a bin name that is not a plain file name, fix the statement to name just the executable.
Example fix
// before mise completion bash --tool gh/cli // after mise completion bash --tool gh
Defensive patterns
Strategy: validation
Validate before calling
fn plain_name(s: &str) -> bool { !s.is_empty() && !s.contains(['/', '\\']) && s != "." && s != ".." }
assert!(plain_name(tool) && plain_name(shell)); Type guard
fn is_plain_file_name(s: &str) -> bool { !s.is_empty() && !s.contains('/') && !s.contains('\\') && s != "." && s != ".." } Try / catch
if !is_plain_file_name(tool) || !is_plain_file_name(shell) { return Err("invalid completion cache identity".into()); }
let script = completion_script(&config, tool, shell)?; Prevention
- Always pass bare tool/command names, never paths, to `mise completion --tool`.
- Use one of the canonical shell names: bash, zsh, fish, pwsh.
- Validate bin names in packslip statements before publishing.
When it happens
Trigger: Calling completion_script (via `mise completion <shell> --tool <tool>`) where packslip::command_name(tool) or the shell argument resolves to a value that is not a plain file name — e.g. a tool name containing '/' or a shell string with directory components.
Common situations: A tool name containing slashes or unusual characters; passing a malformed shell identifier; a packslip naming a binary with a path-like name.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- cli-spec entry names {bin:?} in format {format:?}
- packslip: list_identity_prefix must be a non-empty string
- packslip: list_identity_prefix requires an issuer
- the packslip names an executable {:?}, which is not a plain
- the packslip names an artifact {:?}, which is not a plain fi
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/84eee37a0c3303fa.
Report an issue: GitHub.