jdx/mise · error

generated mise usage spec

Error message

generated mise usage spec

What it means

mise generates its CLI completion/usage spec by serializing the clap `Cli` definition to KDL via `Cli::to_kdl()` and parsing it back. If clap's own output cannot be re-parsed by the usage parser, this `.expect()` panics — it is a build-time-consistency invariant between two internal representations that must never drift.

Source

Thrown at src/cli/usage.rs:32

        flag.conflicts.retain(|selector| selector != "TASK");
        flag.requires.retain(|selector| selector != "TASK");
        flag.required_if.retain(|selector| selector != "TASK");
        flag.required_unless.retain(|selector| selector != "TASK");
    }
    let mut mount = usage::SpecMount::new("mise tasks --usage".to_string());
    mount.synopsis = Some("[TASK] [ARGS]…".to_string());
    command.mounts.push(mount);
    command.restart_token = Some(":::".to_string());
}

/// mise's own usage spec, with everything clap cannot express applied.
///
/// Shared with `mise mcp`, which answers "what does this command do" from the
/// same `effect=` data this prints. Two constructions would drift, and the one
/// an agent reads is the one that must not.
pub(super) fn spec() -> usage::Spec {
    {
        let mut spec: usage::Spec = Cli::to_kdl().parse().expect("generated mise usage spec");

        // Enable "naked" task completions: `mise foo` completes like `mise run foo`
        spec.default_subcommand = Some("run".to_string());

        // `run`/`tasks run` redeclare some root globals as their own non-global flags and
        // add shorts the root global lacks (`-r`/`--raw`, `-S`/`--silent`, see
        // `cli::run::Run`). Those flags used to be promoted back to global here so the
        // completion parser would still recognize them before a task name (mise#10069);
        // jdx/usage#738 makes the parser scan across any known flag, global or not, and
        // bind each word to the flag it was read as, so the promotion is no longer needed.
        if let Some(run) = spec.cmd.subcommands.get_mut("run") {
            prepare_task_runner(run);
        }

        if let Some(tasks_run) = spec
            .cmd
            .subcommands
            .get_mut("tasks")

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Report the panic with the mise version and command to the mise repository (this is a code bug, not user error)
  2. Rebuild from a clean checkout (`mise run clean && mise run build`) to rule out stale artifacts
  3. Check for a recent clap dependency update in Cargo.lock and pin/revert it if this appeared after `cargo update`
  4. Use the latest released mise, where the clap/usage pair is known compatible

Example fix

// before
let mut spec: usage::Spec = Cli::to_kdl().parse().expect("generated mise usage spec");
// after
let mut spec: usage::Spec = Cli::to_kdl().parse()
    .wrap_err_with(|| format!("failed to parse generated usage spec: {}", Cli::to_kdl()))?;
Defensive patterns

Strategy: fallback

Validate before calling

# In CI before relying on completions:
target/debug/mise usage >/dev/null || echo "usage spec generation broken"

Try / catch

// When embedding spec generation:
let spec = match std::panic::catch_unwind(mise_usage::spec) {
    Ok(s) => s,
    Err(_) => return Err(anyhow!("mise usage spec generation panicked; report upstream")),
};

Prevention

When it happens

Trigger: A clap attribute or flag definition that the usage KDL parser does not understand (new/odd clap syntax, unusual value names); a mismatched `clap` and `clap_usage`-style parser version after a dependency bump; local modifications to command definitions.

Common situations: Contributors adding a new CLI flag with exotic attributes then running `mise usage` or generating completions; dependency updates changing clap serialization output.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/7a8b4c0b8d6a0199. Report an issue: GitHub.