astrid-runtime/astrid · error

legacy capsule directory {id} does not match manifest id {}

Error message

legacy capsule directory {id} does not match manifest id {}

What it means

Each legacy capsule directory name is treated as the capsule id, and migration cross-checks it against the package name declared in the capsule's Capsule.toml manifest. A mismatch means the directory no longer reliably identifies the capsule, so migration refuses to proceed for that entry.

Source

Thrown at crates/astrid-capsule-install/src/storage/migration.rs:134

    let mut children = read_dir_sorted(&native)?;
    let mut report = LegacyCapsuleMigrationReport::default();
    let registry = store.capsules();
    let owner = StateOwner::Principal(uid);
    for (target, target_metadata) in children.drain(..) {
        if target_metadata.file_type().is_symlink() || !target_metadata.is_dir() {
            bail!(
                "legacy capsule entry is not a regular directory: {}",
                target.display()
            );
        }
        let id = target
            .file_name()
            .and_then(|name| name.to_str())
            .ok_or_else(|| anyhow::anyhow!("legacy capsule entry has a non-UTF-8 name"))?;
        let manifest = astrid_capsule::discovery::load_manifest(&target.join("Capsule.toml"))
            .with_context(|| format!("read legacy capsule manifest {id}"))?;
        if manifest.package.name != id {
            bail!(
                "legacy capsule directory {id} does not match manifest id {}",
                manifest.package.name
            );
        }
        let meta_bytes = fs::read(target.join("meta.json"))
            .with_context(|| format!("read legacy capsule metadata {id}"))?;
        let meta: CapsuleMeta = serde_json::from_slice(&meta_bytes)
            .with_context(|| format!("decode legacy capsule metadata {id}"))?;
        if meta.version != manifest.package.version {
            bail!("legacy capsule metadata version differs for {id}");
        }
        // Released pre-authority installs are admitted only through the
        // existing one-time verifier. It pins their exact manifest,
        // capabilities, and executable before any durable publication.
        // Relocated homes keep receipts hashed from a previous absolute
        // path; rebind a unique leftover onto this target first.
        rebind_relocated_legacy_authority_receipt(home, &target, &manifest, workspace_targets)
            .with_context(|| format!("rebind relocated leftover authority for {id}"))?;

View on GitHub (pinned to affd8760f4)

Solutions

  1. Rename the directory so it exactly matches manifest.package.name in its Capsule.toml
  2. Restore the original package.name in Capsule.toml to match the directory name
  3. Remove the stale/mismatched directory if it is a leftover copy
  4. Reinstall the capsule cleanly so directory and manifest agree

Example fix

# before
capsules/my-capsule-backup/Capsule.toml -> name = "my-capsule"
# after
mv capsules/my-capsule-backup capsules/my-capsule
Defensive patterns

Strategy: validation

Validate before calling

fn ids_agree(capsule_dir: &Path) -> Result<(), String> {
    let id = capsule_dir.file_name().unwrap().to_string_lossy().to_string();
    let manifest = astrid_capsule::discovery::load_manifest(&capsule_dir.join("Capsule.toml"))
        .map_err(|e| e.to_string())?;
    if manifest.package.name != id { return Err(format!("dir {id} != manifest {}", manifest.package.name)); }
    Ok(())
}

Try / catch

if let Err(e) = migrate_native_capsules(home, store) {
    if e.to_string().contains("does not match manifest id") {
        eprintln!("rename the capsule directory to match its Capsule.toml name, then retry");
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: The capsule directory was renamed manually after install; the manifest's package.name was edited in place; the directory was copied under a different name (e.g. my-capsule-2, my-capsule-backup).

Common situations: Users renaming folders to keep old versions around; hand-edited Capsule.toml during development; restored backups that renamed directories.

Related errors


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