{"record":{"id":"86f6fb7d6b26fb53","repo":"astrid-runtime/astrid","slug":"selected-capsule-is-not-in-signed-lock","errorCode":null,"errorMessage":"selected capsule '{}' is not in signed lock","messagePattern":"selected capsule '(.+?)' is not in signed lock","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init_signed_source.rs","lineNumber":97,"sourceCode":"/// Resolve each member to bytes and prove those bytes match the signed lock.\npub(super) async fn resolve_signed_capsules(\n    selected: &[DistroCapsule],\n    bundle: &SignedDistroBundle,\n    staging: &Path,\n) -> anyhow::Result<Vec<DistroCapsule>> {\n    let signed_by_name: HashMap<&str, &super::super::distro::lock::LockedCapsule> = bundle\n        .lock\n        .capsules\n        .iter()\n        .map(|capsule| (capsule.name.as_str(), capsule))\n        .collect();\n    let mut resolved = Vec::with_capacity(selected.len());\n    for capsule in selected {\n        let signed = signed_by_name\n            .get(capsule.name.as_str())\n            .copied()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"selected capsule '{}' is not in signed lock\", capsule.name)\n            })?;\n        let pinned_tag = signed.resolved_ref.as_deref().or(capsule.tag.as_deref());\n        let archive_path = staging.join(format!(\"{}.capsule\", capsule.name));\n        if let Some(local_source) =\n            resolve_local_capsule_archive(&capsule.source, bundle.manifest_path.as_deref())\n                .with_context(|| format!(\"resolve signed capsule {}\", capsule.name))?\n        {\n            std::fs::copy(&local_source, &archive_path).with_context(|| {\n                format!(\n                    \"copy signed capsule {} from {}\",\n                    capsule.name,\n                    local_source.display()\n                )\n            })?;\n        } else {\n            if capsule.source.starts_with('.') || capsule.source.starts_with('/') {\n                bail!(\n                    \"signed Distro member '{}' must resolve to a prebuilt .capsule archive\",","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_signed_source.rs#L79-L115","documentation":"When resolving capsules for a signed distro source, each selected capsule must also appear in the maintainer's signed lock. If a selected capsule's name is not found in the signed-by-name map, the selection references a capsule outside the signed lock, which cannot be authenticated. The library stops resolution to avoid installing unverified capsules.","triggerScenarios":"`resolve_signed_capsules` looks up each selected capsule in `signed_by_name`; a miss raises this error. Happens when the local request/manifest selects a capsule name absent from the fetched signed lock (Distro.lock), e.g. after renaming or adding a capsule without re-signing the lock.","commonSituations":"Selecting a newly added capsule before the maintainer re-signed Distro.lock; stale local cache of the signed source; typo in the selected capsule name; pinning a capsule from a different distro not covered by this lock.","solutions":["Update/re-fetch the signed distro source so Distro.lock includes the selected capsule (maintainer re-sign and publish)","Remove or correct the selected capsule name so it matches an entry in the signed lock","Check for typos in the capsule selection","Use a lock file that covers all capsules you intend to select"],"exampleFix":"# before\nselected = [\"new-capsule\"]  # absent from signed lock\n# after\nselected = [\"existing-capsule\"]  # or re-fetch signed source containing new-capsule","handlingStrategy":"validation","validationCode":"fn selection_covered(selected: &[CapsuleId], lock: &DistroLock) -> Vec<String> {\n    selected.iter().filter(|c| !lock.capsules.iter().any(|s| s.name == c.name)).map(|c| c.name.clone()).collect()\n}\n// empty result = safe to proceed","typeGuard":null,"tryCatchPattern":"match res {\n    Err(e) if e.to_string().contains(\"not in signed lock\") => refetch_signed_source_and_retry(),\n    other => other,\n}","preventionTips":["Re-fetch the signed source after maintainers add capsules","Validate selection names against the lock before resolution","Watch for capsule renames between distro versions","Avoid cross-distro capsule selections"],"tags":["cli","signed-source","lock","capsule"],"backgroundTag":"resource-not-found","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"}