jdx/mise · error · eyre::Report
brew-cask: binary target contains NUL
Error message
brew-cask: binary target contains NUL
What it means
binary_target_path converts a cask 'binary' artifact target into the destination PathBuf (under the brew prefix, /usr/local, or $APPDIR). Before any filesystem work it rejects targets containing a NUL byte, since NUL can never occur in a valid filename and would truncate the path at the OS boundary. In practice this indicates corrupted cask data or deliberate path injection.
Source
Thrown at src/system/packages/brew/cask.rs:6131
}
Ok(roots)
}
fn is_appdir_binary_target(target_name: &str) -> bool {
target_name.starts_with("$APPDIR/")
}
fn allowed_binary_target_roots_display(roots: &[PathBuf]) -> String {
roots
.iter()
.map(|root| root.display().to_string())
.collect::<Vec<_>>()
.join(" or ")
}
fn binary_target_path(target_name: &str, appdir: &Path) -> Result<PathBuf> {
if target_name.contains('\0') {
bail!("brew-cask: binary target contains NUL");
}
if let Some(relative) = target_name.strip_prefix("$APPDIR/") {
let relative = Path::new(relative);
if relative.components().next().is_none()
|| relative
.components()
.any(|component| !matches!(component, Component::Normal(_)))
{
bail!("brew-cask: binary $APPDIR target '{target_name}' must stay below Applications");
}
if !allowed_appdir_roots()?.iter().any(|root| root == appdir) {
bail!("brew-cask: invalid appdir '{}'", appdir.display());
}
return Ok(appdir.join(relative));
}
if target_name.contains("$APPDIR") {
bail!("brew-cask: $APPDIR must prefix a binary target");
}View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Inspect the cask's binary stanza (`brew info --json=v2 --cask <token>`, tap source) for garbage characters
- Remove the offending tap (`brew untap <tap>`) if it is third-party
- Clear mise's cached cask data (`mise cache clear`) and retry
- Update mise for the latest hardening and parser fixes
Defensive patterns
Strategy: type-guard
Type guard
fn is_clean_binary_target(name: &str) -> bool {
!name.contains('\0')
} Try / catch
match binary_target_path(name, &appdir) {
Ok(p) => p,
Err(e) if e.to_string().contains("contains NUL") => {
warn!("dropping corrupted binary target {name:?}");
continue;
}
Err(e) => Err(e),
} Prevention
- Treat NUL bytes in artifact targets as corruption — investigate the tap or cache instead of retrying
- Validate tap JSON before installing casks from untrusted sources
When it happens
Trigger: A cask 'binary' artifact target string containing '\0' — from tap JSON, cached cask data, or a stored receipt — reaching binary_target_path during install/link.
Common situations: Corrupted cache or receipt JSON; a malicious tap attempting path injection into bin targets; truncated downloads of tap metadata.
Related errors
- brew-cask: app target contains NUL
- brew-cask: app target '{target_name}' 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/c31ec00467d54b42.
Report an issue: GitHub.