astrid-runtime/astrid · error

capsule identity mismatch: expected '{expected}', manifest d

Error message

capsule identity mismatch: expected '{expected}', manifest declares '{}'

What it means

This error is thrown by install_from_local_path_checked_authorized_for_principal_in_workspace when a locally inspected capsule manifest's capsule id does not match the expected identity the caller supplied (ExpectedCapsuleIdentity). The install API requires that the capsule you asked to install is exactly the capsule the manifest declares; any divergence aborts the install before any state is mutated. It is a pre-flight identity check protecting against installing the wrong capsule under an authorized request.

Source

Thrown at crates/astrid-capsule-install/src/local.rs:507

    home: &AstridHome,
    options: InstallOptions,
    target_principal: &PrincipalId,
    expected: &CapsuleId,
    expected_version: Option<&str>,
    workspace_root: Option<&Path>,
    decision: &AuthorityDecision,
    workspace_layout: &WorkspaceLayout,
) -> anyhow::Result<InstallOutput> {
    let inspection = inspect_directory_for_principal_in_workspace(
        source_dir,
        home,
        target_principal,
        options.workspace,
        workspace_root,
        workspace_layout,
    )?;
    if inspection.capsule_id != *expected {
        bail!(
            "capsule identity mismatch: expected '{expected}', manifest declares '{}'",
            inspection.capsule_id
        );
    }
    if let Some(expected_version) = expected_version
        && inspection.version != expected_version
    {
        bail!(
            "capsule version mismatch for '{expected}': expected '{expected_version}', manifest declares '{}'",
            inspection.version
        );
    }
    let authority = authorize_install(&inspection, decision)?;
    install_from_local_path_internal(
        source_dir,
        home,
        options,
        target_principal,

View on GitHub (pinned to affd8760f4)

Solutions

  1. Open the Capsule.toml in the source directory and check package.name
  2. Pass an expected id that exactly matches package.name, or fetch the manifest first and derive the expected identity from it
  3. If the manifest name is wrong, correct package.name in Capsule.toml and retry
  4. Verify you are pointing at the intended source_dir, not a sibling capsule directory

Example fix

// before
let out = install_from_local_path_checked_authorized_for_principal_with_layout(&src, &"app-core".into(), None, ...)?;
// after
let manifest: Manifest = toml::from_str(&std::fs::read_to_string(src.join("Capsule.toml"))?)?;
let expected = CapsuleId::new(manifest.package.name.clone())?;
let out = install_from_local_path_checked_authorized_for_principal_with_layout(&src, &expected, None, ...)?;
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_expected_capsule(src: &Path, expected: &CapsuleId) -> anyhow::Result<()> {
    let manifest: Manifest = toml::from_str(&std::fs::read_to_string(src.join("Capsule.toml"))?)?;
    let id = CapsuleId::new(manifest.package.name.clone())?;
    anyhow::ensure!(&id == expected, "source declares {id}, expected {expected}");
    Ok(())
}

Type guard

fn manifest_matches(manifest: &Manifest, expected: &CapsuleId) -> bool {
    CapsuleId::new(manifest.package.name.clone()).map(|id| &id == expected).unwrap_or(false)
}

Try / catch

match install_..._checked_authorized(...) {
    Err(e) if e.to_string().contains("capsule identity mismatch") => {
        // re-derive expected identity from the manifest and retry once
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling install_from_local_path_checked_authorized_for_principal_with_layout / ..._in_workspace with an expected capsule id that differs from the `package.name` in the source directory's Capsule.toml, e.g. pointing expected='app-core' at a directory whose manifest declares 'app-utils'.

Common situations: Stale cached path or wrong source_dir passed after a rename of the capsule; copy-pasting an install command for a different capsule; the manifest was edited (package.name changed) after the expected identity was computed; typos in the expected id casing.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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