jdx/mise · error

brew-cask: binary artifact

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.

Solutions

  1. 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).
  2. If the symlink target should exist on this machine (e.g. a system library), install that dependency so the link resolves.
  3. Uninstall and reinstall the cask to restage a clean payload — interrupted staging can leave broken links.
  4. 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

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


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

Appendix: 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)