{"record":{"id":"4fbc4bf451cbb5d6","repo":"astrid-runtime/astrid","slug":"capsule-projection-path-is-not-utf-8","errorCode":null,"errorMessage":"capsule projection path is not UTF-8: {}","messagePattern":"capsule projection path is not UTF-8: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":1633,"sourceCode":"    /// Inventory a projection without traversing redirects or special files.\n    #[cfg(not(all(target_arch = \"wasm32\", target_os = \"unknown\")))]\n    fn inventory_projection_files(root: &Path) -> anyhow::Result<ProjectionInventory> {\n        fn walk(\n            root: &Path,\n            directory: &Path,\n            inventory: &mut ProjectionInventory,\n        ) -> anyhow::Result<()> {\n            for entry in std::fs::read_dir(directory).map_err(|error| {\n                anyhow::anyhow!(\"read capsule projection {}: {error}\", directory.display())\n            })? {\n                let entry = entry\n                    .map_err(|error| anyhow::anyhow!(\"read capsule projection entry: {error}\"))?;\n                let path = entry.path();\n                let relative = path.strip_prefix(root).map_err(|_| {\n                    anyhow::anyhow!(\"capsule projection escaped its root: {}\", path.display())\n                })?;\n                let relative_text = relative.to_str().ok_or_else(|| {\n                    anyhow::anyhow!(\"capsule projection path is not UTF-8: {}\", path.display())\n                })?;\n                let metadata = std::fs::symlink_metadata(&path).map_err(|error| {\n                    anyhow::anyhow!(\"inspect capsule projection {}: {error}\", path.display())\n                })?;\n                let file_type = metadata.file_type();\n                if file_type.is_symlink() {\n                    anyhow::bail!(\n                        \"capsule projection contains a symbolic link: {}\",\n                        path.display()\n                    );\n                }\n                if file_type.is_dir() {\n                    inventory.directories.insert(relative_text.to_owned());\n                    walk(root, &path, inventory)?;\n                } else if file_type.is_file() {\n                    inventory.files.insert(relative_text.to_owned());\n                } else {\n                    anyhow::bail!(","sourceCodeStart":1615,"sourceCodeEnd":1651,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L1615-L1651","documentation":"Thrown when a path inside the capsule projection cannot be converted to a UTF-8 string via `Path::to_str`. The inventory requires relative path text (for hashing/registration), so non-UTF-8 filenames are rejected explicitly.","triggerScenarios":"A file or directory inside the projection has a name that is not valid UTF-8 (raw bytes from a tarball, legacy encoding, or attacker-controlled names).","commonSituations":"Extracting archives built on systems with non-UTF-8 filenames (e.g. Latin-1) into the projection; macOS NFD vs NFC issues do not trigger this, but raw-byte names do.","solutions":["Rebuild the capsule with UTF-8-only filenames.","Sanitize/normalize filenames at capsule build time to enforce UTF-8.","Locate the offending path (printed in the error) and rename or remove it.","If the name is correct but encoded differently, transcode it to UTF-8 before projecting."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn all_paths_utf8(dir: &Path) -> anyhow::Result<()> {\n    for entry in std::fs::read_dir(dir)? {\n        let p = entry?.path();\n    anyhow::ensure!(p.to_str().is_some(), \"non-UTF-8 path: {}\", p.display());\n        if p.is_dir() { all_paths_utf8(&p)?; }\n    }\n    Ok(())\n}","typeGuard":"fn is_utf8_path(p: &Path) -> bool { p.to_str().is_some() }","tryCatchPattern":null,"preventionTips":["Enforce UTF-8 filenames at capsule build time.","Normalize/transcode names when ingesting archives from non-UTF-8 systems.","Fail fast in CI on non-UTF-8 paths in capsule sources."],"tags":["filesystem","encoding","rust","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}