{"record":{"id":"7798cf34b8431876","repo":"astrid-runtime/astrid","slug":"authority-receipt-has-an-empty-capsule-id","errorCode":null,"errorMessage":"authority receipt has an empty capsule id","messagePattern":"authority receipt has an empty capsule id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-capsule-install/src/storage.rs","lineNumber":738,"sourceCode":"    let value: toml::Value = toml::from_str(&manifest).context(\"parse capsule manifest\")?;\n    let id = value\n        .get(\"package\")\n        .and_then(|package| package.get(\"name\"))\n        .and_then(toml::Value::as_str)\n        .ok_or_else(|| anyhow::anyhow!(\"Capsule.toml has no package.name\"))?;\n    let version = value\n        .get(\"package\")\n        .and_then(|package| package.get(\"version\"))\n        .and_then(toml::Value::as_str)\n        .ok_or_else(|| anyhow::anyhow!(\"Capsule.toml has no package.version\"))?;\n    Ok((id.to_owned(), version.to_owned()))\n}\n\nfn authority_capsule_id(authority: &[u8]) -> anyhow::Result<String> {\n    let authority: InstalledAuthority =\n        serde_json::from_slice(authority).context(\"decode authority receipt for package id\")?;\n    if authority.capsule_id.is_empty() {\n        bail!(\"authority receipt has an empty capsule id\");\n    }\n    Ok(authority.capsule_id)\n}\n\n/// Build a deterministic gzip/tar package from a checked directory.\npub fn canonical_capsule_archive(source_dir: &Path) -> anyhow::Result<Vec<u8>> {\n    let mut entries = Vec::new();\n    collect_entries(source_dir, source_dir, &mut entries)?;\n    if !entries\n        .iter()\n        .any(|(path, _)| path == Path::new(\"Capsule.toml\"))\n    {\n        bail!(\"capsule source has no Capsule.toml\");\n    }\n    entries.sort_by(|left, right| left.0.cmp(&right.0));\n\n    let output = Vec::new();\n    let encoder = GzEncoder::new(output, Compression::default());","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-capsule-install/src/storage.rs#L720-L756","documentation":"Raised by authority_capsule_id while building a package id from the capsule's authority.json receipt: the decoded InstalledAuthority has an empty capsule_id field. The library requires a non-empty capsule id to construct a valid package identity during publish_directory_package.","triggerScenarios":"Publishing a directory/legacy package whose authority.json decodes successfully but has `capsule_id: \"\"` — e.g. a hand-written or truncated receipt, or an older receipt format missing the field defaulting to an empty string.","commonSituations":"Manually authored authority.json in a capsule directory; receipts damaged by truncation or bad merges; receipts generated by an old tool version that did not set capsule_id.","solutions":["Open authority.json in the capsule source and set `capsule_id` to the capsule's actual identifier.","Regenerate the authority receipt with the current toolchain instead of editing it by hand.","If the receipt is unrecoverable, re-publish the capsule from its original source to produce a fresh receipt."],"exampleFix":"// before: authority.json\n{ \"capsule_id\": \"\" }\n\n// after\n{ \"capsule_id\": \"my-capsule-0.1.0\" }","handlingStrategy":"validation","validationCode":"fn check_authority(authority_json: &[u8]) -> Result<(), String> {\n    let v: serde_json::Value = serde_json::from_slice(authority_json).map_err(|e| e.to_string())?;\n    match v[\"capsule_id\"].as_str() {\n        Some(id) if !id.is_empty() => Ok(()),\n        _ => Err(\"capsule_id missing or empty\".into()),\n    }\n}","typeGuard":"fn has_capsule_id(v: &serde_json::Value) -> bool {\n    v.get(\"capsule_id\").and_then(|x| x.as_str()).map_or(false, |s| !s.is_empty())\n}","tryCatchPattern":"match publish_directory_package(...) {\n    Err(e) if e.to_string().contains(\"empty capsule id\") => { regenerate_authority_receipt()?; retry(); }\n    other => other?,\n}","preventionTips":["Never author authority.json by hand; generate it with the toolchain","Validate receipts (non-empty capsule_id) before publishing","Keep receipts in version control to catch truncation"],"tags":["authority","capsule","empty-field"],"backgroundTag":"empty-required-field","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}