{"record":{"id":"95effa0426195675","repo":"astrid-runtime/astrid","slug":"durable-capsule-id-metadata-names-a-component-ab","errorCode":null,"errorMessage":"durable capsule {id} metadata names a component absent from its archive","messagePattern":"durable capsule (.+?) metadata names a component absent from its archive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-capsule-install/src/storage.rs","lineNumber":318,"sourceCode":"        };\n        if Path::new(relative)\n            .extension()\n            .is_some_and(|extension| extension.eq_ignore_ascii_case(\"wasm\"))\n        {\n            let archive_hash = blake3::hash(bytes).to_hex().to_string();\n            if authority.wasm_hash_pinned\n                && authority.approved_wasm_hash.as_deref() != Some(archive_hash.as_str())\n            {\n                bail!(\"durable capsule {id} WASM hash differs between authority and archive\");\n            }\n            if metadata.wasm_hash.as_deref() != Some(archive_hash.as_str()) {\n                bail!(\"durable capsule {id} WASM hash differs between metadata and archive\");\n            }\n        } else if metadata.wasm_hash.is_some() {\n            bail!(\"durable capsule {id} metadata names a hash for a non-WASM component\");\n        }\n    } else if metadata.wasm_hash.is_some() {\n        bail!(\"durable capsule {id} metadata names a component absent from its archive\");\n    }\n    let mut effective_capabilities = manifest.capabilities.clone();\n    for component in &manifest.components {\n        if let Some(capabilities) = &component.capabilities {\n            effective_capabilities.merge_from(capabilities);\n        }\n    }\n    if !effective_capabilities\n        .expansions_from(&authority.approved_capabilities)\n        .is_empty()\n    {\n        bail!(\"durable capsule {id} manifest exceeds its authority receipt\");\n    }\n    match verification {\n        ArtifactVerification::Signed(provenance) => {\n            let signer = provenance.signer.to_string();\n            let signature = provenance.signature.to_string();\n            if authority.signer.as_deref() != Some(signer.as_str())","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-capsule-install/src/storage.rs#L300-L336","documentation":"The manifest has no components at all, yet metadata.wasm_hash is Some. The library throws this because a hash naming an executable implies an executable component exists; with an empty component list the metadata references something that cannot exist in the archive. Verification of the durable package fails before it is served.","triggerScenarios":"read_verified_durable_package_for_owner on a capsule whose manifest.components is empty but whose CapsuleMeta carries a wasm_hash value.","commonSituations":"A capsule stripped of its components during re-export; metadata copied from another package; manifest generation that dropped the components section while metadata survived.","solutions":["Add the WASM component back to the manifest/archive and republish.","Set metadata.wasm_hash to None if the capsule is intentionally component-free.","Regenerate both manifest and metadata from the same source tree so they cannot diverge.","Inspect the archive for a manifest that was truncated or mis-authored."],"exampleFix":"// before: empty manifest with metadata hash set\ncomponents: [], wasm_hash: Some(hash)\n// after: either ship the component\ncomponents: vec![Component { path: \"component.wasm\".into(), .. }], wasm_hash: Some(hash)\n// or drop the hash\ncomponents: vec![], wasm_hash: None","handlingStrategy":"validation","validationCode":"if manifest.components.is_empty() && meta.wasm_hash.is_some() {\n    return Err(\"wasm_hash set but manifest has no components\");\n}","typeGuard":"fn has_component_for_hash(manifest: &CapsuleManifest, meta: &CapsuleMeta) -> bool {\n    !manifest.components.is_empty() || meta.wasm_hash.is_none()\n}","tryCatchPattern":"match read_verified_durable_package_for_owner(&store, owner, id).await {\n    Ok(pkg) => pkg,\n    Err(e) if e.to_string().contains(\"names a component absent from its archive\") => {\n        // restore components or clear wasm_hash, then republish\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Generate manifest and metadata from the same source tree in one step.","Validate capsule packages with the same identity checks before shipping.","Review manifests stripped of components during re-export."],"tags":["metadata","manifest","wasm","storage"],"backgroundTag":"schema-validation-failed","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"}