astrid-runtime/astrid · error

selected capsule ' ' is not in signed lock

Error message

selected capsule '{}' is not in signed lock

What it means

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.

Solutions

  1. Update/re-fetch the signed distro source so Distro.lock includes the selected capsule (maintainer re-sign and publish)
  2. Remove or correct the selected capsule name so it matches an entry in the signed lock
  3. Check for typos in the capsule selection
  4. Use a lock file that covers all capsules you intend to select

Example fix

# before
selected = ["new-capsule"]  # absent from signed lock
# after
selected = ["existing-capsule"]  # or re-fetch signed source containing new-capsule
Defensive patterns

Strategy: validation

Validate before calling

fn selection_covered(selected: &[CapsuleId], lock: &DistroLock) -> Vec<String> {
    selected.iter().filter(|c| !lock.capsules.iter().any(|s| s.name == c.name)).map(|c| c.name.clone()).collect()
}
// empty result = safe to proceed

Try / catch

match res {
    Err(e) if e.to_string().contains("not in signed lock") => refetch_signed_source_and_retry(),
    other => other,
}

Prevention

When it happens

Trigger: `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.

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/86f6fb7d6b26fb53. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-cli/src/commands/init_signed_source.rs:97

/// Resolve each member to bytes and prove those bytes match the signed lock.
pub(super) async fn resolve_signed_capsules(
    selected: &[DistroCapsule],
    bundle: &SignedDistroBundle,
    staging: &Path,
) -> anyhow::Result<Vec<DistroCapsule>> {
    let signed_by_name: HashMap<&str, &super::super::distro::lock::LockedCapsule> = bundle
        .lock
        .capsules
        .iter()
        .map(|capsule| (capsule.name.as_str(), capsule))
        .collect();
    let mut resolved = Vec::with_capacity(selected.len());
    for capsule in selected {
        let signed = signed_by_name
            .get(capsule.name.as_str())
            .copied()
            .ok_or_else(|| {
                anyhow::anyhow!("selected capsule '{}' is not in signed lock", capsule.name)
            })?;
        let pinned_tag = signed.resolved_ref.as_deref().or(capsule.tag.as_deref());
        let archive_path = staging.join(format!("{}.capsule", capsule.name));
        if let Some(local_source) =
            resolve_local_capsule_archive(&capsule.source, bundle.manifest_path.as_deref())
                .with_context(|| format!("resolve signed capsule {}", capsule.name))?
        {
            std::fs::copy(&local_source, &archive_path).with_context(|| {
                format!(
                    "copy signed capsule {} from {}",
                    capsule.name,
                    local_source.display()
                )
            })?;
        } else {
            if capsule.source.starts_with('.') || capsule.source.starts_with('/') {
                bail!(
                    "signed Distro member '{}' must resolve to a prebuilt .capsule archive",

View on GitHub (pinned to affd8760f4)