{"record":{"id":"3fb9e5cd9daf62a6","repo":"jdx/mise","slug":"content-level-slsa-verification-found-duplicate-in","errorCode":null,"errorMessage":"content-level SLSA verification found duplicate installed archive path: {}","messagePattern":"content-level SLSA verification found duplicate installed archive path: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/file.rs","lineNumber":2560,"sourceCode":"    let mut buf = [0; 8192];\n    loop {\n        let n = reader.read(&mut buf)?;\n        if n == 0 {\n            break;\n        }\n        hasher.update(&buf[..n]);\n    }\n    Ok(hex::encode(hasher.finalize()))\n}\n\nfn validate_archive_content_files(files: Vec<ArchiveContent>) -> Result<Vec<ArchiveContent>> {\n    if files.is_empty() {\n        bail!(\"content-level SLSA verification found no regular files in archive\");\n    }\n    let mut names = std::collections::HashSet::new();\n    for file in &files {\n        if !names.insert(file.name.clone()) {\n            bail!(\n                \"content-level SLSA verification found duplicate installed archive path: {}\",\n                file.name\n            );\n        }\n    }\n    Ok(files)\n}\n\nfn normalize_archive_content_path(path: &Path, strip_components: usize) -> Result<String> {\n    let mut parts = Vec::new();\n    for component in skip_curdir_components(path) {\n        match component {\n            std::path::Component::Normal(part) => parts.push(part.to_string_lossy().to_string()),\n            std::path::Component::CurDir => {}\n            std::path::Component::ParentDir\n            | std::path::Component::RootDir\n            | std::path::Component::Prefix(_) => {\n                bail!(","sourceCodeStart":2542,"sourceCodeEnd":2578,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/file.rs#L2542-L2578","documentation":"After strip-components normalization, no two entries may map to the same installed path, otherwise provenance subject-name matching would be ambiguous. The HashSet in validate_archive_content_files detects the collision and names the duplicated path.","triggerScenarios":"An archive with multiple top-level directories whose contents repeat (e.g. linux/bin/tool and macos/bin/tool) processed with strip_components = 1 - both entries normalize to bin/tool.","commonSituations":"Multi-platform combined archives where stripping was meant to select one platform directory; tarballs that intentionally contain duplicate paths (later entries would overwrite earlier ones on extraction).","solutions":["Set strip_components to 0 so distinct top-level directories stay distinct","Use a single-platform archive asset instead of a combined one","Fall back to artifact-level verification if the combined layout must be kept"],"exampleFix":"# before\nstrip_components = 1 # collapses linux/bin/tool and macos/bin/tool to bin/tool\n\n# after\nstrip_components = 0","handlingStrategy":"validation","validationCode":"// multi-top-level-dir archives must not be stripped\nif strip_components > 0 {\n    let tops = top_level_dirs(&archive, format)?;\n    anyhow::ensure!(tops.len() <= 1, \"multiple top-level dirs ({tops:?}) + strip would collide paths\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use strip_components only on archives with exactly one wrapper directory","Prefer single-platform assets over combined multi-platform archives","Check for duplicate paths with tar -tzf | sort | uniq -d before enabling content verification"],"tags":["slsa","verification","duplicate","strip-components","archive","rust","mise"],"backgroundTag":"duplicate-archive-path","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}