astrid-runtime/astrid · error
legacy capsule metadata version differs for {id}
Error message
legacy capsule metadata version differs for {id} What it means
The legacy capsule's meta.json records an installed version that must agree with the version in Capsule.toml. If serde-decoded meta.version differs from manifest.package.version, the install is internally inconsistent and migration aborts for that capsule.
Source
Thrown at crates/astrid-capsule-install/src/storage/migration.rs:144
}
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}"))?;
verify_installed_authority(home, &target, &manifest)
.with_context(|| format!("verify legacy capsule authority {id}"))?;
let authority = read_installed_authority(home, &target)?.ok_or_else(|| {
anyhow::anyhow!("legacy capsule {id} authority verification produced no receipt")
})?;
if authority.capsule_id != id || authority.version != manifest.package.version {
bail!("legacy capsule authority identity differs for {id}");
}
let source_authority_bytes = read_installed_authority_bytes(home, &target)?
.ok_or_else(|| anyhow::anyhow!("legacy capsule {id} authority receipt disappeared"))?;View on GitHub (pinned to affd8760f4)
Solutions
- Reinstall the capsule so meta.json and Capsule.toml are regenerated consistently
- Update meta.json's version to match the manifest only if you are certain the install matches
- Delete the inconsistent install and migrate a clean copy
- Restore both files from the same backup generation
Example fix
// before (meta.json)
{"version": "1.0.0"} // Capsule.toml says 1.2.0
// after
reinstall capsule so meta.json records 1.2.0 Defensive patterns
Strategy: validation
Validate before calling
fn versions_agree(capsule_dir: &Path) -> Result<(), String> {
let manifest = astrid_capsule::discovery::load_manifest(&capsule_dir.join("Capsule.toml")).map_err(|e| e.to_string())?;
let meta: CapsuleMeta = serde_json::from_slice(&std::fs::read(capsule_dir.join("meta.json")).map_err(|e| e.to_string())?)
.map_err(|e| e.to_string())?;
if meta.version != manifest.package.version { return Err("meta/manifest version mismatch".into()); }
Ok(())
} Try / catch
if let Err(e) = migrate_native_capsules(home, store) {
if e.to_string().contains("metadata version differs") {
eprintln!("reinstall the capsule so meta.json matches Capsule.toml, then retry");
} else { return Err(e); }
} Prevention
- Upgrade capsules through the installer, never by hand-editing Capsule.toml
- Restore meta.json and Capsule.toml from the same backup generation
- Check both files after any interrupted upgrade
- Keep capsule processes from writing version metadata during migration
When it happens
Trigger: meta.json was written for an older/newer install than the current Capsule.toml; the manifest was upgraded without reinstalling; a partial update overwrote one of the two files.
Common situations: Manually replacing Capsule.toml with a newer version during development; interrupted upgrade leaving stale meta.json; restored backup mixing file generations.
Related errors
- legacy capsule metadata has no WASM hash
- legacy capsule {id} metadata changed before retirement
- installed capsule identity/version differs from its authorit
- WASM capsule has no BLAKE3 hash in meta.json
- durable capsule {id} version differs across package records
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/9ff12a6e4d9d9043.
Report an issue: GitHub.