astrid-runtime/astrid · error
durable contracts blob disappeared
Error message
durable contracts blob disappeared
What it means
refresh_canonical_contracts_from_registry re-resolves the durable contracts WIT blob from installed packages; if every candidate package lookup returns None the blob variable stays None and the function throws 'durable contracts blob disappeared', an internal invariant failure meaning the registry no longer holds content that was expected to exist.
Solutions
- Reinstall the capsule package that provides the durable contracts WIT
- Re-run the install/refresh so the registry repopulates the package set
- Clear stale install state and perform a fresh install
- Report as a bug if the package is present but lookup still fails (invariant violation)
Defensive patterns
Strategy: retry
Validate before calling
fn canonical_blob_present(home: &Path) -> bool {
std::fs::read(canonical_contracts_path(home)).is_ok()
} Try / catch
match refresh_canonical_contracts_from_registry(...) {
Err(e) if e.to_string().contains("durable contracts blob disappeared") => {
eprintln!("contracts package missing; reinstall and retry refresh");
// reinstall_package(); retry once
}
other => other?,
} Prevention
- Avoid concurrent installs/uninstalls while a refresh is running
- Keep the contracts-providing package installed before lifecycle refreshes
- Verify install state after upgrades before triggering refresh
When it happens
Trigger: Calling refresh_canonical_contracts_from_registry when the wit_file(relative) lookups over the installed packages all fail — e.g. the package providing the contracts WIT was uninstalled, upgraded, or its internal layout changed between resolution and refresh.
Common situations: Concurrent install/uninstall racing the refresh; partial upgrade that removed the old package before writing the new canonical blob; corrupted capsule-install state directory.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- all capsule install(s) failed — not writing Distro.lock…
- capsule capabilities changed after authority decision
- capsule content changed after authority decision
- capsule disappeared during durable contracts scan
- capsule disappeared during introspection
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/23b95d0ff5d4c809.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-capsule-install/src/contracts.rs:192
.metadata()
.wit_files
.keys()
.filter(|relative| {
Path::new(relative.as_str())
.file_name()
.and_then(|name| name.to_str())
== Some(CONTRACTS_WIT_BASENAME)
})
.min()
else {
continue;
};
blob = package.wit_file(relative).map(ToOwned::to_owned);
if blob.is_some() {
break;
}
}
let content = blob.ok_or_else(|| anyhow::anyhow!("durable contracts blob disappeared"))?;
let canonical = canonical_contracts_path(home);
if std::fs::read(&canonical).is_ok_and(|existing| existing == content) {
return Ok(());
}
write_canonical_atomic(&canonical, &content)
.with_context(|| format!("failed to write canonical {}", canonical.display()))
}
/// BLAKE3 hex of the daemon canonical `astrid-contracts.wit`, or `None`
/// when the canonical file is absent or unreadable.
/// Absent canonical is a normal state (fresh home, daemon never booted) —
/// the caller degrades silently rather than treating it as an error.
#[must_use]
pub fn canonical_contracts_b3(home: &AstridHome) -> Option<String> {
let bytes = std::fs::read(canonical_contracts_path(home)).ok()?;
Some(blake3::hash(&bytes).to_hex().to_string())
}
View on GitHub (pinned to affd8760f4)