jdx/mise · error
brew-cask: binary artifact '{}' was staged but symlink targe
Error message
brew-cask: binary artifact '{}' was staged but symlink target '{}' does not exist What it means
During linking, mise expects each binary artifact to exist as a regular file at its staged caskroom path. Here the path exists as a symlink (symlink_metadata says so) but is_file() is false — the symlink's target does not exist, i.e. the staged payload contains a dangling symlink where a runnable binary was declared. The message reports both the binary stanza source and the (missing) link target.
Source
Thrown at src/system/packages/brew/cask.rs:4877
fn cask_appdir(apps: &[AppArtifact]) -> Result<PathBuf> {
let prefix_app_dir = prefix::prefix().join("Applications");
for app in apps {
if app_target_path(app.target_name())?.starts_with(&prefix_app_dir) {
return Ok(prefix_app_dir);
}
}
target_app_dir()
}
fn link_binary(caskroom: &Path, appdir: &Path, binary: &BinaryArtifact) -> Result<()> {
let caskroom_binary = caskroom_binary_path(caskroom, appdir, binary)?;
if !caskroom_binary.is_file() {
if caskroom_binary
.symlink_metadata()
.is_ok_and(|metadata| metadata.file_type().is_symlink())
{
let target = std::fs::read_link(&caskroom_binary)?;
bail!(
"brew-cask: binary artifact '{}' was staged but symlink target '{}' does not exist",
binary.source,
target.display()
);
}
bail!(
"brew-cask: binary artifact '{}' was not staged",
binary.source
);
}
let target = binary.target_path(appdir)?;
if let Some(parent) = target.parent() {
create_dir_all_elevating(parent)?;
}
make_symlink_elevating(&caskroom_binary, &target)?;
Ok(())
}
View on GitHub (pinned to 6f52dcdf99)
Solutions
- Adjust the binary stanza's source to point at the real executable file rather than a symlink (check the error's reported target path to see where the link was supposed to go).
- If the symlink target should exist on this machine (e.g. a system library), install that dependency so the link resolves.
- Uninstall and reinstall the cask to restage a clean payload — interrupted staging can leave broken links.
- Report the cask upstream if the app genuinely ships dangling symlinks in its distribution.
Example fix
# before — stanza points at a symlink whose target is absent "binary": ["MyApp.app/Contents/MacOS/tool-link"] # after — point at the real binary "binary": ["MyApp.app/Contents/MacOS/tool"]
Defensive patterns
Strategy: validation
Validate before calling
# after staging, confirm every declared binary resolves to a real file for b in "$(jq -r '.binaries[].source' meta.json)"; do P="<caskroom>/$b" [ -f "$P" ] || [ -f "$(readlink -f "$P" 2>/dev/null)" ] || echo "broken: $P -> $(readlink "$P" 2>/dev/null)" done
Prevention
- Point binary stanzas at real executables, never at bundled symlinks.
- Test casks on a clean machine (or CI) so absolute-path symlinks fail before users see them.
- Reinstall to restage whenever an install was interrupted.
When it happens
Trigger: A cask binary stanza matches a path inside the staged payload that is a symlink whose destination is absent — e.g. an app bundle shipping symlinks to absolute paths like /usr/lib/... that do not exist in this environment, or payload relocation having rewritten the link to a now-invalid location. Read via std::fs::read_link at src/system/packages/brew/cask.rs:4877.
Common situations: macOS apps bundling symlinks meant to resolve only on a full macOS install; installing casks on Linux where framework paths differ; partially extracted or interrupted downloads that left broken links; payloads where the binary stanza pointed at a symlink instead of the real executable.
Related errors
- brew-cask: binary artifact '{}' was not staged
- brew-cask: command wrapper '{}' was not staged
- brew-cask: invalid binary target '{}'
- brew-cask: binary artifact '{}' was staged but symlink targe
- brew-cask: staged symlink path escaped extraction root: {}
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/acaa630602329011.
Report an issue: GitHub.