jdx/mise · error
no usable completion for
Error message
no usable {shell} completion for {}: {} What it means
mise's packslip backend tries each registered completion source for a shell and collects every failure. When none yield a script, `completion_script` gives up with this error listing each source's failure reason. It means the tool's packslip manifest offers no completion script mise can render for that shell.
Solutions
- Check which shells the tool's packslip publishes and request one it ships (`mise completion bash --tool <tool>`)
- Verify network access / proxy settings so the completion assets can download
- Run with MISE_DEBUG=1 to see each skipped source's underlying error and address it (404, checksum, parse failure)
- Generate completions with the tool itself and install them manually (e.g. `<tool> completions bash > ...`), or file an issue upstream for missing shell support
Example fix
// before mise completion fish --tool some-tool # no usable fish completion // after mise completion bash --tool some-tool # shell the packslip actually ships
Defensive patterns
Strategy: fallback
Validate before calling
mise completion bash --tool <tool> --dry-run 2>/dev/null || echo 'no completions for this shell'
Try / catch
match mise::packslip::completion_script(shell, tv) {
Ok(script) => install(script),
Err(e) => fallback_to_native_completions(tool, shell, e),
} Prevention
- Check the tool's packslip manifest for supported shells before scripting completion setup
- Prefer shells the vendor publishes (bash/zsh/fish) for packslip tools
- Handle per-source skip reasons in logs (MISE_DEBUG=1) to catch asset download failures early
When it happens
Trigger: Running `mise completion <shell> --tool <tool>` (or an install flow that fetches completions) for a packslip-installed tool where every candidate source errored — e.g. the manifest references a completion file that failed to download or a shell variant the manifest doesn't ship.
Common situations: Requesting completions for a shell the vendor doesn't publish (e.g. fish when only bash/zsh are shipped); offline or proxy-blocked downloads of completion assets; a malformed or stale packslip manifest pointing at missing assets.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- loads completions eagerly, so mise cannot leave it a stub…
- brew-cask: failed to generate
- Check shell must not be empty
- --install takes the executable's name, not a tool id; run…
- invalid completion specification path
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/06886a80a9b7fe15.
Report an issue: GitHub.
Appendix: source
Thrown at src/packslip.rs:1572
}
};
match attempt {
Ok(script) if script.trim().is_empty() => {
skipped.push("nothing was printed".to_string())
}
Ok(script) => {
if ran_tool
&& let Some(dir) = cache.parent()
&& file::create_dir_all(dir).is_ok()
{
let _ = file::write_atomic(&cache, &script);
}
return Ok(script);
}
Err(err) => skipped.push(err.to_string()),
}
}
bail!(
"no usable {shell} completion for {}: {}",
tv.style(),
skipped.join("; ")
)
}
/// Take turns generating, so that of the shells completing one command at
/// once the first runs the tool and the rest read what it cached. The lock
/// lives beside the cache, shared by every process that shares the install,
/// and is taken off the runtime's threads.
///
/// A read-only install cannot be locked and does not need to be: nothing
/// will be cached there either, so each shell generates its own script
/// rather than being refused a completion.
async fn lock_generation(cache: &Path) -> Option<fslock::LockFile> {
let lock_path = cache.with_extension("lock");
let taken = tokio::task::spawn_blocking(move || -> Result<fslock::LockFile> {
if let Some(dir) = lock_path.parent() {View on GitHub (pinned to 533346cc37)