jdx/mise · error

install from exe

Error message

install from exe

What it means

link_binary symlinks a staged binary from the Caskroom into the target bin directory. If the staged path is a symlink but not a file, mise reads the link target and bails when that target does not exist — i.e. the cask's flight steps staged a symlink whose destination was never extracted into the stage.

Source

Thrown at src/plugins/core/swift.rs:91

                tempdir_in(tv.install_path().parent().unwrap())?
                    .path()
                    .to_path_buf()
            };
            CmdLineRunner::new(pkgutil_path())
                .arg("--expand-full")
                .arg(tarball_path)
                .arg(&tmp)
                .with_pr(ctx.pr.as_ref())
                .env_values(tv.install_env())
                .execute()?;
            file::remove_all(tv.install_path())?;
            file::rename(
                tmp.join(format!("swift-{version}-RELEASE-osx-package.pkg"))
                    .join("Payload"),
                tv.install_path(),
            )?;
        } else if cfg!(windows) {
            todo!("install from exe");
        } else {
            file::untar(
                tarball_path,
                &tv.install_path(),
                file::ExtractionFormat::TarGz,
                &file::ExtractOptions {
                    strip_components: 1,
                    pr: Some(ctx.pr.as_ref()),
                    ..Default::default()
                },
            )?;
        }
        Ok(())
    }

    fn symlink_bins(&self, tv: &ToolVersion) -> Result<()> {
        let usr_bin = tv.install_path().join("usr").join("bin");
        let bin_dir = tv.install_path().join("bin");

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Inspect the staged Caskroom directory (ls -la <prefix>/Caskroom/<token>/<version>/) and check what the dangling symlink points at
  2. Clear the cask's Caskroom dir and cached archive, then reinstall so extraction re-runs cleanly
  3. Compare with an install via upstream brew to see if the cask itself is broken
  4. Report the cask token plus the symlink target to mise if metadata and archive disagree
Defensive patterns

Strategy: validation

Validate before calling

// after staging, before linking: verify the staged binary resolves
if caskroom_binary.symlink_metadata().is_ok_and(|m| m.file_type().is_symlink()) {
    let t = std::fs::read_link(&caskroom_binary)?;
    if !t.exists() { /* repair or abort before link_binary */ }
}

Try / catch

match link_binary(&caskroom, &appdir, &binary) {
    Err(e) if e.to_string().contains("symlink target") => {
        // stale stage: wipe and re-extract once, then retry
        fs::remove_dir_all(&caskroom)?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: A cask archive contains a symlink whose target was filtered out (e.g. under __MACOSX), renamed by a preflight step, or points outside the extracted set; relocation rewrote the symlink so it no longer resolves inside the Caskroom.

Common situations: Casks shipping relative symlinks to versioned files (libfoo.1 -> libfoo.1.2.3) where the real file landed elsewhere; upstream cask layout changes; partially extracted or interrupted prior installs leaving stale symlinks.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/71fcd027c3669410. Report an issue: GitHub.