{"record":{"id":"ecb9fabcdfe56440","repo":"unicity-aos/aos-ce","slug":"aos-capsule-directory-must-be-valid-utf-8-for-the-toml","errorCode":null,"errorMessage":"AOS capsule directory must be valid UTF-8 for the TOML manifest","messagePattern":"AOS capsule directory must be valid UTF-8 for the TOML manifest","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/unicity-aos-bootstrap/src/lib.rs","lineNumber":799,"sourceCode":"                \"embedded distro has no capsules\",\n            )\n        })?;\n    for capsule in capsules {\n        let source = capsule\n            .get(\"source\")\n            .and_then(toml::Value::as_str)\n            .ok_or_else(|| {\n                io::Error::new(io::ErrorKind::InvalidData, \"embedded capsule has no source\")\n            })?;\n        let asset = Path::new(source).file_name().ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"embedded capsule source has no asset\",\n            )\n        })?;\n        let absolute = capsule_dir.join(asset);\n        let absolute = absolute.to_str().ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"AOS capsule directory must be valid UTF-8 for the TOML manifest\",\n            )\n        })?;\n        capsule[\"source\"] = toml::Value::String(absolute.to_owned());\n    }\n    toml::to_string_pretty(&manifest)\n        .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))\n}\n\n#[cfg(test)]\nmod tests {\n    use super::{\n        AosHome, RUNTIME_EXECUTABLE_NAMES, UNICITY_CE_MANIFEST, capsule_assets_from_manifest,\n        materialize_manifest, runtime_binary_name, runtime_daemon_binary_name,\n    };\n    use std::ffi::OsString;\n    use std::fs;","sourceCodeStart":781,"sourceCodeEnd":817,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/unicity-aos-bootstrap/src/lib.rs#L781-L817","documentation":"During manifest materialization, `materialize_manifest` joins the AOS capsule directory with an asset path and calls `Path::to_str()`. If the resulting absolute path cannot be represented as valid UTF-8, it cannot be embedded as a TOML string value, so an `io::Error` with kind `InvalidInput` is raised. The library throws this because TOML string values require valid UTF-8 and text-substituted manifests are explicitly avoided.","triggerScenarios":"Calling `ensure_unicity_ce_manifest` or a test path via `materialized_capsule_paths_are_toml_serialized_without_text_substitution` where the capsule directory path (or asset path under it) contains bytes that are not valid UTF-8 — e.g. paths built from raw bytes or containing Latin-1 encoded names.","commonSituations":"Mounting or extracting a capsule under a directory whose name was produced by a tool that does not enforce UTF-8 (e.g. zip archives with non-UTF-8 filename flags, NFS exports with legacy encodings), or constructing the capsule dir from `OsString`/byte data on Linux.","solutions":["Rename the capsule directory (and its parents) so the full path is valid UTF-8, e.g. `mv` it to an ASCII/UTF-8 path.","Check the path with `std::path::Path::to_str()` in your own setup before invoking the bootstrap and fail early with a clear message.","If the path came from an environment variable or config, re-encode or normalize it (e.g. `String::from_utf8` on the source bytes) to UTF-8.","On Linux, avoid building paths from raw `OsStrExt::as_bytes` unless they are known-valid UTF-8."],"exampleFix":"// before\ncapsule_dir = PathBuf::from(OsString::from_vec(raw_bytes));\n\n// after\nlet capsule_dir = PathBuf::from(String::from_utf8(raw_bytes)\n    .expect(\"capsule directory must be valid UTF-8\"));","handlingStrategy":"validation","validationCode":"let capsule_dir: &Path = ...;\nif capsule_dir.to_str().is_none() {\n    return Err(anyhow!(\"capsule directory path is not valid UTF-8: {:?}\", capsule_dir));\n}","typeGuard":"fn is_utf8_path(p: &Path) -> bool { p.to_str().is_some() }","tryCatchPattern":null,"preventionTips":["Always create capsule directories from UTF-8 strings, never raw bytes.","Validate paths with `Path::to_str()` during setup, before invoking the bootstrap.","Normalize archive extractions with UTF-8 filename decoding (e.g. unzip with -O UTF-8)."],"tags":["filesystem","encoding","toml","rust"],"backgroundTag":"invalid-argument-format","analyzedSha":"f6f22024fb1e8d122f28a1b4a9f75aee448ae839","analyzedAt":"2026-09-13T03:04:44.565Z","contentChangedAt":"2026-09-13T03:04:44.565Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}