jdx/mise · error

content-level SLSA verification found duplicate installed…

Error message

content-level SLSA verification found duplicate installed archive path: {}

What it means

Content-level SLSA verification hashes every regular file at its installed path. If two files in the archive map to the same installed path after strip-component normalization, the digest set is ambiguous, so mise rejects the archive instead of producing a non-reproducible verification.

Solutions

  1. Inspect the archive with `tar tf <file> | sort | uniq -d` (after applying strip_components) to find duplicate entries
  2. Rebuild or re-download the archive from upstream; a clean official release usually has no duplicate entries
  3. Adjust strip_components in the recipe if a single normalization step is collapsing distinct paths
  4. Pin to an earlier upstream version whose release archives were not affected
Defensive patterns

Strategy: validation

Validate before calling

tar -tf tool.tar.gz | sed 's|^\./||' | sort | uniq -d

Prevention

When it happens

Trigger: `mise install` with content-level SLSA verification where two archive entries (often differing only by case, a `./` prefix, or a duplicate entry appended to the tarball) normalize to the same installed path.

Common situations: Hand-built or duplicated-entry tarballs; archives mixing `./dir/file` and `dir/file` entries; case-insensitive filesystem collisions between two archive paths that differ only in case.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/3fb9e5cd9daf62a6. Report an issue: GitHub.

Appendix: source

Thrown at src/file.rs:2751

    let mut buf = [0; 8192];
    loop {
        let n = reader.read(&mut buf)?;
        if n == 0 {
            break;
        }
        hasher.update(&buf[..n]);
    }
    Ok(hex::encode(hasher.finalize()))
}

fn validate_archive_content_files(files: Vec<ArchiveContent>) -> Result<Vec<ArchiveContent>> {
    if files.is_empty() {
        bail!("content-level SLSA verification found no regular files in archive");
    }
    let mut names = std::collections::HashSet::new();
    for file in &files {
        if !names.insert(file.name.clone()) {
            bail!(
                "content-level SLSA verification found duplicate installed archive path: {}",
                file.name
            );
        }
    }
    Ok(files)
}

fn normalize_archive_content_path(path: &Path, strip_components: usize) -> Result<String> {
    let mut parts = Vec::new();
    for component in skip_curdir_components(path) {
        match component {
            std::path::Component::Normal(part) => parts.push(part.to_string_lossy().to_string()),
            std::path::Component::CurDir => {}
            std::path::Component::ParentDir
            | std::path::Component::RootDir
            | std::path::Component::Prefix(_) => {
                bail!(

View on GitHub (pinned to 533346cc37)