astrid-runtime/astrid · error

Distro.lock capsule ' ' expects version , but the daemon…

Error message

Distro.lock capsule '{}' expects version {}, but the daemon registry reports {}

What it means

During reuse of a previously generated grant set, the CLI cross-checks each capsule recorded in Distro.lock against the running daemon's registry. A capsule whose locked version differs from the registry's reported version means the daemon has a different build installed than the lockfile expects, so reusing the locked grants would be unsafe and the operation bails.

Solutions

  1. Sync the installed capsule version in the daemon with the version pinned in Distro.lock (reinstall the capsule at the locked version).
  2. Regenerate Distro.lock so it records the version actually present in the daemon registry.
  3. Re-run init/grant after the daemon has the correct capsules installed instead of reusing the grant set.
  4. Check out the Distro.lock matching the deployed capsule set or revert the capsule upgrade.

Example fix

// Distro.lock
capsules = [{ name = "my-capsule", version = "1.2.0", hash = "blake3:..." }]
# after: install matching version in daemon or update lock
# astrid install my-capsule@1.2.0  (then re-run grant)
Defensive patterns

Strategy: validation

Validate before calling

let entry = registry.get(&capsule.name).ok_or_else(|| anyhow!("capsule absent from registry"))?;
if !capsule.version.is_empty() && entry.version != capsule.version {
    return Err(anyhow!("version mismatch for {}", capsule.name));
}

Try / catch

match resync_and_relock().await {
    Err(e) if e.to_string().contains("expects version") => reinstall_locked_version(capsule)?,
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: Call validated_grant_set_for_reuse with a Distro.lock containing a non-empty capsule.version that does not exactly match entry.version returned by the daemon registry lookup.

Common situations: Upgrading or downgrading a capsule outside the lockfile, a daemon running older/newer installed capsules than the repo's Distro.lock, switching branches where the lockfile pins a different version, or a stale daemon registry after a partial reinstall.

Related errors


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

Appendix: source

Thrown at crates/astrid-cli/src/commands/init_grant.rs:320

        {
            astrid_core::kernel_api::KernelResponse::CapsuleMetadata(entries) => entries,
            astrid_core::kernel_api::KernelResponse::Error(message) => bail!(message),
            other => bail!("unexpected capsule metadata response: {other:?}"),
        };
        let mut installed = Vec::with_capacity(locked.len());
        for capsule in locked {
            let expected = CapsuleId::new(capsule.name.clone())?;
            let entry = entries
                .iter()
                .find(|entry| entry.name == capsule.name)
                .ok_or_else(|| {
                    anyhow::anyhow!(
                        "Distro.lock capsule '{}' is absent from the daemon registry",
                        capsule.name
                    )
                })?;
            if !capsule.version.is_empty() && entry.version != capsule.version {
                bail!(
                    "Distro.lock capsule '{}' expects version {}, but the daemon registry reports {}",
                    capsule.name,
                    capsule.version,
                    entry.version
                );
            }
            let expected_hash = capsule.hash.strip_prefix("blake3:");
            if expected_hash != entry.wasm_hash.as_deref() {
                bail!(
                    "Distro.lock capsule '{}' hash disagrees with the daemon registry",
                    capsule.name
                );
            }
            installed.push(expected.as_str().to_owned());
        }
        Ok::<_, anyhow::Error>(installed)
    }
    .await;

View on GitHub (pinned to affd8760f4)