{"record":{"id":"bcabe850302c4bc7","repo":"unicity-aos/aos-ce","slug":"embedded-capsule-source-does-not-match-package-package","errorCode":null,"errorMessage":"embedded capsule source does not match package {package}","messagePattern":"embedded capsule source does not match package (.+?)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/unicity-aos-bootstrap/src/lib.rs","lineNumber":698,"sourceCode":"                .is_none()\n            || components.next().is_some()\n            || relative.extension() != Some(OsStr::new(\"capsule\"))\n        {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\"embedded capsule source is not canonical: {source}\"),\n            ));\n        }\n        let asset = relative\n            .file_name()\n            .expect(\"validated capsule source has a filename\")\n            .to_str()\n            .ok_or_else(|| {\n                io::Error::new(io::ErrorKind::InvalidData, \"capsule asset is not UTF-8\")\n            })?\n            .to_owned();\n        if asset != format!(\"{package}.capsule\") {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\"embedded capsule source does not match package {package}\"),\n            ));\n        }\n        if assets.contains(&asset) {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\"embedded distro selects duplicate capsule asset {asset}\"),\n            ));\n        }\n        assets.push(asset);\n    }\n    Ok(assets)\n}\n\nfn validate_capsule_dir(path: &Path, expected: &[String]) -> io::Result<PathBuf> {\n    let metadata = fs::symlink_metadata(path).map_err(|error| {\n        io::Error::new(","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/unicity-aos-bootstrap/src/lib.rs#L680-L716","documentation":"This error is thrown by capsule_assets_from_manifest when a capsule entry in the embedded Community Edition TOML manifest has a `source` path whose filename is not `<package>.capsule`, where `<package>` is the entry's `name` field. The bootstrap library enforces a strict naming convention so that embedded capsule assets can be located and validated deterministically; any drift between the package name and the asset filename breaks that invariant.","triggerScenarios":"Editing the embedded UNICITY_CE_MANIFEST so a `[capsule]` entry's `source` filename does not equal the `name` field plus the `.capsule` extension (e.g. name=\"foo\", source=\"capsules/foo_v2.capsule\"). Any call to capsule_dir_with, prepare_unicity_ce_init, or install_capsule_fixtures then fails.","commonSituations":"Renaming a capsule package without renaming its .capsule asset file (or vice versa); hand-editing the embedded manifest; adding a new capsule entry with a versioned or suffixed filename; copy-pasting a capsule entry and updating only one of the two fields.","solutions":["Rename the asset in the `source` path so its filename is exactly `{name}.capsule` for that manifest entry","Or update the entry's `name` field to match the existing filename (minus the .capsule extension)","Re-run prepare_unicity_ce_init to confirm the embedded manifest passes validation"],"exampleFix":"// before\ncapsule = [{ name = \"kernel-core\", source = \"capsules/kernel-core-v2.capsule\" }]\n// after\ncapsule = [{ name = \"kernel-core\", source = \"capsules/kernel-core.capsule\" }]","handlingStrategy":"validation","validationCode":"fn capsule_source_matches(capsule: &toml::Value) -> bool {\n    let name = capsule.get(\"name\").and_then(|v| v.as_str());\n    let source = capsule.get(\"source\").and_then(|v| v.as_str());\n    match (name, source) {\n        (Some(n), Some(s)) => {\n            std::path::Path::new(s).file_name().map(|f| f.to_string_lossy())\n                == Some(format!(\"{n}.capsule\"))\n        }\n        _ => false,\n    }\n}","typeGuard":"fn is_valid_capsule_entry(c: &toml::Value) -> bool {\n    c.get(\"name\").and_then(|v| v.as_str()).is_some()\n        && c.get(\"source\").and_then(|v| v.as_str()).is_some()\n}","tryCatchPattern":"match bootstrap::prepare_unicity_ce_init(&home) {\n    Err(e) if e.to_string().contains(\"does not match package\") => {\n        eprintln!(\"Manifest entry name/source mismatch: {e}\");\n    }\n    Err(e) => return Err(e),\n    Ok(v) => v,\n}","preventionTips":["Always keep the asset filename as exactly `{name}.capsule` in manifest entries","Add a CI check that validates every [[capsule]] entry's name/source pairing","Avoid renaming packages without renaming their .capsule assets in the same commit"],"tags":["rust","manifest","naming-convention","capsules"],"backgroundTag":"invalid-config-value","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"}