{"record":{"id":"72968cabb444b87b","repo":"jdx/mise","slug":"content-level-slsa-verification-found-no-regular-f","errorCode":null,"errorMessage":"content-level SLSA verification found no regular files in archive","messagePattern":"content-level SLSA verification found no regular files in archive","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/file.rs","lineNumber":2555,"sourceCode":"    validate_archive_content_files(files)\n}\n\nfn sha256_reader(reader: &mut impl Read) -> Result<String> {\n    let mut hasher = Sha256::new();\n    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()),","sourceCodeStart":2537,"sourceCodeEnd":2573,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/file.rs#L2537-L2573","documentation":"After walking the whole archive, validate_archive_content_files requires at least one regular file. An archive whose entries are all directories (or one from which no file entries could be enumerated) fails because verifying 'nothing' is meaningless and would silently pass a broken provenance check.","triggerScenarios":"archive_content_files runs on an archive containing only directory entries, or on a truncated/garbage file that parsed but yielded zero file entries.","commonSituations":"The wrong asset was downloaded (an empty or metadata-only artifact, or a saved error page named .tar.gz); an asset matcher grabbed a placeholder artifact from a release.","solutions":["Inspect the downloaded artifact with tar -tzf or unzip -l and confirm it actually lists files","Fix the asset URL/pattern in the backend or aqua config so the real payload archive is downloaded","Verify the download size/checksum against the release to catch truncated downloads"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// sanity-check the artifact before verification\nlet f = ExtractionFormat::from_path(&archive)?;\nif f.is_tar_archive() {\n    let t = tar::Archive::new(File::open(&archive)?);\n    let has_files = t.entries()?.filter_map(|e| e.ok())\n        .any(|e| e.header().entry_type().is_file());\n    anyhow::ensure!(has_files, \"archive contains no regular files; wrong or truncated asset?\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify downloaded asset size/checksum against the release before verification runs","List archives (tar -tzf / unzip -l) in CI when asset URLs are dynamic or matcher-driven"],"tags":["slsa","verification","archive","empty-archive","rust","mise"],"backgroundTag":"empty-archive","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}