jdx/mise · error

mise cannot derive completions from a

Error message

mise cannot derive completions from a {format} spec

What it means

derive_from_spec generates a completion script from a CLI spec file using the tool's own usage tooling. Only the `usage` format is supported; any other declared format (e.g. clap_complete, shtool) bails with this error so the caller can fall back to another resource source.

Solutions

  1. Set the spec format to "usage" if the tool emits a usage spec
  2. Convert/produce a usage-format spec for the tool (e.g. via usage CLI)
  3. Remove the spec-based completion resource and rely on an exec-based one instead
  4. Validate the spec parses (an invalid usage spec also fails after this check)

Example fix

// before (packslip)
// format = "clap_complete"
// after
// format = "usage"
Defensive patterns

Strategy: fallback

Validate before calling

if (format !== 'usage') console.warn(`format ${format} unsupported; will fall back`);

Try / catch

try { script = await deriveFromSpec(format, bin, spec, shell) } catch (e) { if (/cannot derive completions from a .* spec/.test(e.message)) { script = await execBasedCompletion(); } else { throw e; } }

Prevention

When it happens

Trigger: A packslip completion resource declares a spec with format set to something other than "usage" and mise tries to derive completions from that spec file.

Common situations: Packslip written for a tool that emits a different spec format, copy-pasted format field from another tool, upstream switched spec format.

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/c448e4cbd0c57eec. Report an issue: GitHub.

Appendix: source

Thrown at src/packslip.rs:1403

        .envs(env)
        .prepend_path(vec![install_path.join(MISE_BINS_DIR)])?
        .current_dir(work.path())
        .stdin(std::process::Stdio::null())
        .stderr(std::process::Stdio::null())
        .with_timeout(timeout)
        .read_isolated(4 * 1024 * 1024)
        .await?;
    if output.trim().is_empty() {
        bail!("resource command produced no output");
    }
    Ok(output)
}

/// Derive a completion script from a CLI spec with the consumer's own
/// tooling. Only the `usage` format is known.
fn derive_from_spec(format: &str, bin: &str, spec: &Path, shell: &str) -> Result<String> {
    if format != "usage" {
        bail!("mise cannot derive completions from a {format} spec");
    }
    // Validate before returning a loader, so an invalid preferred spec still
    // falls through to another resource source.
    file::read_to_string(spec)?
        .parse::<usage::Spec>()
        .map_err(|err| eyre!("invalid usage specification: {err}"))?;
    let shell = usage_rs::complete::Shell::from_name(shell)
        .ok_or_else(|| eyre!("unsupported completion shell: {shell}"))?;
    let path = completions::encode_spec_path(spec);
    let script = usage_rs::script::script_for("mise", bin, shell);
    Ok(script.replace(
        " __complete_word__ ",
        &format!(" __usage_complete_word {path} "),
    ))
}

/// The `shell` completion script for `tool`, from the packslip of the
/// version that is active right now.

View on GitHub (pinned to 533346cc37)