jdx/mise · error

the packslip lists executable {} in {}, but the archive hold

Error message

the packslip lists executable {} in {}, but the archive holds no such file

What it means

After validating the declared executable name, mise locates the file inside the extracted install directory using the manifest's declared path. If no file exists at that path in the archive, the install fails because a listed executable cannot be linked. This catches manifests that don't match the actual archive contents.

Source

Thrown at src/backend/packslip.rs:935

    /// Put every executable the packslip names into the install's bin dir
    /// under the name it should have on PATH.
    fn link_bins(tv: &ToolVersion, artifact: &Artifact) -> Result<()> {
        if artifact.bin.is_empty() {
            return Ok(());
        }
        let install_path = tv.install_path();
        let bins_dir = install_path.join(MISE_BINS_DIR);
        file::create_dir_all(&bins_dir)?;
        for bin in &artifact.bin {
            if !file::is_plain_file_name(&bin.name) {
                bail!(
                    "the packslip names an executable {:?}, which is not a plain file name",
                    bin.name
                );
            }
            let Some(src) = locate_in_install(&install_path, &bin.path) else {
                bail!(
                    "the packslip lists executable {} in {}, but the archive holds no such file",
                    bin.path,
                    artifact.name
                );
            };
            file::make_executable(&src)?;
            let dst = bins_dir.join(&bin.name);
            if dst.exists() || dst.is_symlink() {
                file::remove_all(&dst)?;
            }
            file::make_symlink_or_copy(&src, &dst)?;
        }
        Ok(())
    }

    /// Every version the vendor published, before stamps are applied.
    async fn vendor_versions(&self, raw_opts: &ToolVersionOptions) -> Result<Vec<VersionInfo>> {
        let project = self.project()?;

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Check the actual archive contents (`tar tf`) and correct the manifest's `bin.path` to the real file location
  2. Report the mismatch to the vendor so the manifest/archive pair is fixed
  3. Re-download the artifact in case a partial/corrupt extraction dropped files

Example fix

// before (packslip manifest)
[[bin]]
name = "mytool"
path = "bin/mytool"
// after (archive actually has target/release/mytool)
[[bin]]
name = "mytool"
path = "target/release/mytool"
Defensive patterns

Strategy: validation

Validate before calling

fn bins_present(archive_listing: &[String], bins: &[(String, String)]) -> Vec<String> {
    bins.iter()
        .filter(|(_, path)| !archive_listing.iter().any(|f| f == path))
        .map(|(name, path)| format!("{name}: {path}"))
        .collect()
}

Prevention

When it happens

Trigger: link_bins during install when locate_in_install cannot find `bin.path` inside the tool's install directory for the given artifact — the manifest lists a file the archive doesn't contain (wrong archive attached, renamed binary, path casing mismatch).

Common situations: Vendor re-uploaded an archive with renamed binaries but didn't update the packslip manifest; wrong-platform artifact attached to the release entry; case-sensitive filesystem makes `Tool` vs `tool` fail on Linux but not macOS.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/ace9dcde81e29aec. Report an issue: GitHub.