jdx/mise · error

brew-cask: invalid completion target '{target_name}'

Error message

brew-cask: invalid completion target '{target_name}'

What it means

completion_filename normalizes a completion target for the target shell (stripping or adding prefixes like '_' and suffixes like '.ps1'/'.zsh' per CompletionShell). If that normalization produces an empty string — for example a target that is only dots, only an extension, or otherwise reduces to nothing — mise rejects it with this bail instead of trying to build a path from an empty filename.

Source

Thrown at src/system/packages/brew/cask.rs:4495

            }
        }
        CompletionShell::Zsh => {
            if filename.starts_with('_') {
                filename.to_string()
            } else {
                format!("_{stem}")
            }
        }
        CompletionShell::Pwsh => {
            if filename.ends_with(".ps1") {
                filename.to_string()
            } else {
                format!("{stem}.ps1")
            }
        }
    };
    if normalized.is_empty() {
        bail!("brew-cask: invalid completion target '{target_name}'");
    }
    Ok(normalized)
}

fn caskroom_completion_path(caskroom: &Path, target: &Path) -> Result<PathBuf> {
    let prefix = prefix::prefix();
    let relative = target.strip_prefix(&prefix).map_err(|_| {
        eyre!(
            "brew-cask: completion target '{}' must be under {}",
            target.display(),
            prefix.display()
        )
    })?;
    if relative.components().next().is_none() {
        bail!(
            "brew-cask: invalid completion target '{}'",
            target.display()
        );

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Set the completion target to a real filename with a non-empty stem, e.g. '_tool' for zsh or 'tool.ps1' for Pwsh.
  2. Validate the cask metadata loads as you expect (jq/python) — an empty string usually means the field was never populated or was misnested.
  3. If generating cask metadata programmatically, assert the normalized filename is non-empty before emitting the stanza.

Example fix

# before
"completions": { "target": "" }

# after
"completions": { "target": "_mytool" }
Defensive patterns

Strategy: validation

Validate before calling

# require a non-empty stem in every completion target
jq -e '.completions[] | select((.target | split(".") | first | length) > 0)' meta.json >/dev/null || echo 'empty completion target'

Prevention

When it happens

Trigger: A cask completion target such as '.', '..', '' or a value whose stem is empty after shell-specific normalization (e.g. a Pwsh target that normalizes to just '.ps1' with an empty stem, or a zsh target reducing to '_'). The check `if normalized.is_empty()` at src/system/packages/brew/cask.rs:4495 fires after the match on CompletionShell.

Common situations: Malformed or machine-generated cask metadata with an empty/placeholder target field; YAML/JSON field misindentation that yields an empty string; adversarial or fuzzed cask JSON probing mise's filename handling.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/f456e1e5b64d7106. Report an issue: GitHub.