jdx/mise · error · eyre::Report
brew-cask:{}: invalid {kind} {field} path {}
Error message
brew-cask:{}: invalid {kind} {field} path {} What it means
After accepting base == "staged_path", mise runs the flight-path object's "path" string through validate_flight_relative_path (src/system/packages/brew/cask.rs:3905), which rejects absolute paths and any '..' component. This bail fires when the declared relative path would escape the staged cask location, so mise refuses before creating any link. It is a containment check: flight paths must stay inside the staged directory they are anchored to.
Source
Thrown at src/system/packages/brew/cask.rs:5872
"brew-cask:{}: unsupported {kind} {field} metadata format",
cask.token
)
})?;
let base = match object.get("base").and_then(Value::as_str) {
Some("staged_path") => FlightPathBase::StagedPath,
Some(base) => bail!(
"brew-cask:{}: unsupported {kind} {field} base {}",
cask.token,
base
),
None => bail!("brew-cask:{}: unsupported {kind} {field} base", cask.token),
};
let path = object
.get("path")
.and_then(Value::as_str)
.ok_or_else(|| eyre!("brew-cask:{}: unsupported {kind} {field} path", cask.token))?;
if validate_flight_relative_path(path).is_err() {
bail!(
"brew-cask:{}: invalid {kind} {field} path {}",
cask.token,
path
)
}
Ok(FlightPath {
base,
path: path.to_string(),
})
}
fn collect_pkg_receipt_ids(value: &Value, pkg_ids: &mut Vec<String>) {
let Some(object) = value.as_object() else {
return;
};
let Some(metadata) = object.get("uninstall") else {
return;
};View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Inspect the cask payload (`brew info --json=v2 --cask <token>`) and confirm the flight-path "path" field is a plain relative path with no leading '/' and no '..' segments
- If the cask is from a third-party tap, report/fix the artifact stanza upstream or remove the tap
- Clear mise's cached cask JSON (`mise cache clear`) and re-fetch in case the copy is corrupted
- Update mise in case a newer release supports the artifact form this cask uses
Defensive patterns
Strategy: type-guard
Type guard
use std::path::{Component, Path};
fn is_valid_flight_path_str(p: &str) -> bool {
let path = Path::new(p);
!path.is_absolute()
&& !path.components().any(|c| matches!(c, Component::ParentDir))
&& !p.contains('\0')
} Try / catch
match parse_flight_path(&value) {
Ok(fp) => fp,
Err(e) if e.to_string().contains("invalid") && e.to_string().contains("path") => {
warn!("rejecting unsafe flight path in cask artifact");
continue;
}
Err(e) => return Err(e),
} Prevention
- Never author cask flight paths with leading '/' or '..' segments
- Audit third-party taps before adding them — malformed artifact stanzas are rejected at install time
- Re-fetch cask JSON after editing a local cask instead of relying on cached copies
When it happens
Trigger: A cask artifact flight-path object whose "path" starts with '/' (e.g. "/Applications/Foo.app") or contains a ParentDir segment (e.g. "../Foo.app") reaching this parser during install/upgrade.
Common situations: Hand-edited or malformed cask definitions in a tap; corrupted cached cask JSON; a malicious or typosquatted tap attempting to link outside the staged path.
Related errors
- brew-cask: app target '{target_name}' must not contain '..'
- brew-cask: binary target '{}' must not contain '..'
- mise upgrade --monorepo is not implemented yet
- brew-cask: refusing generic artifact copy outside Homebrew p
- brew-cask: invalid generic artifact parent
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/663879c21f88fb6e.
Report an issue: GitHub.