astrid-runtime/astrid · error
durable capsule {id} metadata names a component absent from
Error message
durable capsule {id} metadata names a component absent from its archive What it means
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.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:318
};
if Path::new(relative)
.extension()
.is_some_and(|extension| extension.eq_ignore_ascii_case("wasm"))
{
let archive_hash = blake3::hash(bytes).to_hex().to_string();
if authority.wasm_hash_pinned
&& authority.approved_wasm_hash.as_deref() != Some(archive_hash.as_str())
{
bail!("durable capsule {id} WASM hash differs between authority and archive");
}
if metadata.wasm_hash.as_deref() != Some(archive_hash.as_str()) {
bail!("durable capsule {id} WASM hash differs between metadata and archive");
}
} else if metadata.wasm_hash.is_some() {
bail!("durable capsule {id} metadata names a hash for a non-WASM component");
}
} else if metadata.wasm_hash.is_some() {
bail!("durable capsule {id} metadata names a component absent from its archive");
}
let mut effective_capabilities = manifest.capabilities.clone();
for component in &manifest.components {
if let Some(capabilities) = &component.capabilities {
effective_capabilities.merge_from(capabilities);
}
}
if !effective_capabilities
.expansions_from(&authority.approved_capabilities)
.is_empty()
{
bail!("durable capsule {id} manifest exceeds its authority receipt");
}
match verification {
ArtifactVerification::Signed(provenance) => {
let signer = provenance.signer.to_string();
let signature = provenance.signature.to_string();
if authority.signer.as_deref() != Some(signer.as_str())View on GitHub (pinned to affd8760f4)
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.
Example fix
// before: empty manifest with metadata hash set
components: [], wasm_hash: Some(hash)
// after: either ship the component
components: vec![Component { path: "component.wasm".into(), .. }], wasm_hash: Some(hash)
// or drop the hash
components: vec![], wasm_hash: None Defensive patterns
Strategy: validation
Validate before calling
if manifest.components.is_empty() && meta.wasm_hash.is_some() {
return Err("wasm_hash set but manifest has no components");
} Type guard
fn has_component_for_hash(manifest: &CapsuleManifest, meta: &CapsuleMeta) -> bool {
!manifest.components.is_empty() || meta.wasm_hash.is_none()
} Try / catch
match read_verified_durable_package_for_owner(&store, owner, id).await {
Ok(pkg) => pkg,
Err(e) if e.to_string().contains("names a component absent from its archive") => {
// restore components or clear wasm_hash, then republish
},
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: read_verified_durable_package_for_owner on a capsule whose manifest.components is empty but whose CapsuleMeta carries a wasm_hash value.
Common situations: A capsule stripped of its components during re-export; metadata copied from another package; manifest generation that dropped the components section while metadata survived.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- durable capsule {id} metadata names a hash for a non-WASM co
- WASM capsule has no BLAKE3 hash in meta.json
- durable capsule {id} WASM hash differs between metadata and
- Distro.lock capsule '{capsule}' declares WASM but has no ins
- Distro.lock capsule '{capsule}' does not declare WASM but in
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/95effa0426195675.
Report an issue: GitHub.