jdx/mise · error

loads completions eagerly, so mise cannot leave it a stub…

Error message

{} loads completions eagerly, so mise cannot leave it a stub; redirect `mise completion {} --tool {tool}` yourself

What it means

mise can emit lazy 'stub' completion scripts that defer to `mise completion` at runtime only for shells it knows how to stub (bash/zsh/fish style deferral). For other shells the packslip tool loads its full completion script eagerly, so mise refuses to install a stub and tells the user to set up the redirect themselves. It is an explicit unsupported-shell guard, not a bug.

Solutions

  1. Add a redirect in your shell config yourself: alias or function so `<tool>` completion loads via `mise completion <shell> --tool <tool>`
  2. Use a stub-supported shell (bash, zsh, fish) for that tool's completions
  3. Load the tool's native completion script directly in your shell config instead of relying on mise's stub
  4. Check mise docs for the current list of stub-capable shells

Example fix

// before (PowerShell $PROFILE relying on mise stub)
mise completion pwsh --tool gh   # errors: cannot leave stub
// after (register the loader yourself)
Register-ArgumentCompleter -Native -CommandName 'gh' -ScriptBlock (mise completion pwsh --tool gh | Out-String | Invoke-Expression)
Defensive patterns

Strategy: fallback

Validate before calling

case "$(basename $SHELL)" in bash|zsh|fish) echo 'stub supported';; *) echo 'manual redirect required';; esac

Try / catch

match mise::packslip::stub(shell, tool) {
    Ok(stub) => write_stub(stub),
    Err(_) => write_manual_redirect(shell, tool), // Register-ArgumentCompleter / equivalent
}

Prevention

When it happens

Trigger: Calling `mise completion <shell> --tool <tool>` (or stub installation during tool install) with a shell outside the stub-supported set, e.g. powershell/nushell, where the packslip tool's completions load eagerly.

Common situations: Using PowerShell or an exotic shell with a packslip-installed tool; scripted dotfile setup that assumes stubs work everywhere; shell migration where the old shell's stub was auto-generated but the new one is not.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/d4e000cb80bb8a24. Report an issue: GitHub.

Appendix: source

Thrown at src/packslip.rs:1769

    $global:{loader}_busy = $true
    try {{
        $__mise_script = @(& mise completion powershell --tool '{tool}' 2>$null) -join "`n"
        if ($__mise_script) {{
            Invoke-Expression $__mise_script
            $__mise_cursor = $cursorPosition - $commandAst.Extent.StartOffset
            $__mise_line = $commandAst.Extent.Text.PadRight([Math]::Max($commandAst.Extent.Text.Length, $__mise_cursor))
            (TabExpansion2 -inputScript $__mise_line -cursorColumn $__mise_cursor).CompletionMatches
        }}
    }} finally {{
        Register-ArgumentCompleter -Native -CommandName '{tool}' -ScriptBlock $function:{loader}
        $global:{loader}_busy = $false
    }}
}}
Register-ArgumentCompleter -Native -CommandName '{tool}' -ScriptBlock $function:{loader}
"#
        ),
        _ => bail!(
            "{} loads completions eagerly, so mise cannot leave it a stub; redirect `mise completion {} --tool {tool}` yourself",
            shell.as_str(),
            shell.as_str()
        ),
    };
    Ok(stub)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_fetch_text_returns_the_body_of_a_reachable_url() {
        let _config = crate::config::Config::get().await.unwrap();
        let mut server = mockito::Server::new_async().await;
        let mock = server
            .mock("GET", "/packslip.sigstore.json")
            .with_status(200)

View on GitHub (pinned to 533346cc37)