jdx/mise · error

brew-cask:{}: invalid {kind} run command path {}

Error message

brew-cask:{}: invalid {kind} run command path {}

What it means

Path-shape validation for run command paths. Two cases bail: (1) base absent (Literal) and the path is relative with more than one component (e.g. "bin/helper.sh") — literal paths must be absolute or a single filename; (2) base is staged_path/appdir/homebrew_prefix and the path is absolute or contains ".." — based paths must stay inside the base directory. This blocks relative-path ambiguity and parent-directory traversal.

Source

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

            "brew-cask:{}: unsupported {kind} run command base {}",
            cask.token,
            base
        ),
        None => FlightPathBase::Literal,
    };
    let path_value = Path::new(path);
    let invalid_absolute_path = base == FlightPathBase::Literal
        && !path_value.is_absolute()
        && path_value.components().count() > 1;
    let invalid_based_path = matches!(
        base,
        FlightPathBase::StagedPath | FlightPathBase::AppDir | FlightPathBase::HomebrewPrefix
    ) && (path_value.is_absolute()
        || path_value
            .components()
            .any(|component| matches!(component, Component::ParentDir)));
    if invalid_absolute_path || invalid_based_path {
        bail!(
            "brew-cask:{}: invalid {kind} run command path {}",
            cask.token,
            path
        );
    }
    Ok(FlightPath {
        base,
        path: path.to_string(),
    })
}

fn parse_flight_guard(cask: &Cask, kind: &str, value: &Value) -> Result<FlightGuard> {
    let object = value.as_object().ok_or_else(|| {
        eyre!(
            "brew-cask:{}: unsupported {kind} run guard metadata format",
            cask.token
        )
    })?;

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. For multi-component relative paths, add the right base: "base": "staged_path" (or appdir/homebrew_prefix)
  2. Keep based paths relative and free of ".." — the base already anchors them
  3. Use literal absolute paths only without a base, and single bare filenames only for PATH-style lookups

Example fix

// before
{"path": "bin/helper.sh"}
// after
{"path": "bin/helper.sh", "base": "staged_path"}
Defensive patterns

Strategy: validation

Validate before calling

use std::path::{Path, Component};

fn run_path_ok(cmd: &serde_json::Value) -> bool {
    let Some(path) = cmd.get("path").and_then(|p| p.as_str()) else { return false; };
    let pv = Path::new(path);
    let base = cmd.get("base").and_then(|b| b.as_str());
    match base {
        None => pv.is_absolute() || pv.components().count() <= 1,
        Some("staged_path" | "appdir" | "homebrew_prefix") => {
            !pv.is_absolute() && !pv.components().any(|c| matches!(c, Component::ParentDir))
        }
        _ => true, // unsupported base handled by its own error
    }
}

Try / catch

match parse_run_command(&cask, kind, Some(&cmd)) {
    Ok(path) => { /* proceed */ }
    Err(e) if e.to_string().contains("invalid") && e.to_string().contains("run command path") => {
        eprintln!("literal paths must be absolute or a single name; based paths must be relative without '..'");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Literal: {"path": "bin/helper.sh"} with no base. Based: {"path": "/etc/x", "base": "appdir"} or {"path": "../../etc/passwd", "base": "staged_path"}. Both set invalid_absolute_path/invalid_based_path and bail with the path echoed.

Common situations: Assuming relative multi-segment paths resolve against the staging dir without declaring a base; porting shell scripts that use ".." navigation; absolute paths left over when converting to based paths.

Related errors


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