astrid-runtime/astrid · error
durable capsule {} has malformed contracts pin
Error message
durable capsule {} has malformed contracts pin What it means
durable_contracts_pin computes the plurality (fleet-wide majority) BLAKE3 contracts pin by scanning every capsule in the owner's durable registry. Each capsule's meta.json `wit_files` map must carry a well-formed BLAKE3-hex pin for astrid-contracts.wit. When the stored pin string is not valid BLAKE3 hex (e.g. truncated, wrong length, non-hex characters), the scan refuses to continue rather than computing a majority over untrustworthy pins.
Source
Thrown at crates/astrid-capsule-install/src/contracts.rs:100
pub fn durable_contracts_pin(
store: &RuntimePrincipalStore,
owner: &StateOwner,
) -> anyhow::Result<Option<String>> {
let registry = store.capsules();
let mut counts = std::collections::BTreeMap::<String, usize>::new();
for summary in registry.list(owner)? {
let Some(package) = read_verified_durable_package_for_owner(store, owner, summary.id())?
else {
bail!(
"capsule {} disappeared during durable contracts scan",
summary.id()
);
};
let Some(pin) = contracts_pin(&package.metadata().wit_files) else {
continue;
};
if !is_blake3_pin(pin) {
bail!(
"durable capsule {} has malformed contracts pin",
summary.id()
);
}
let Some(relative) = package
.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 {
bail!(
"durable capsule {} is missing its pinned contracts blob",View on GitHub (pinned to affd8760f4)
Solutions
- Identify the offending capsule id from the message and rebuild/reinstall it with the current SDK so meta.json's wit_files pin is a proper BLAKE3 hex digest.
- Recompute the pin: `blake3 hash` the vendored astrid-contracts.wit and write that hex into meta.json's wit_files entry for the file.
- If the metadata is unrecoverable, remove and re-publish the capsule to the registry, then re-run the refresh.
Example fix
// before (meta.json wit_files) "deps/astrid-contracts/astrid-contracts.wit": "abc123" // after "deps/astrid-contracts/astrid-contracts.wit": "<full 64-char blake3 hex>"
Defensive patterns
Strategy: validation
Validate before calling
fn is_blake3_pin(pin: &str) -> bool {
pin.len() == 64 && pin.chars().all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase())
}
// before calling the scan, verify each capsule's meta.json pin:
// assert!(is_blake3_pin(pin)); Type guard
fn valid_pin(wit_files: &HashMap<String, String>) -> Option<&String> {
contracts_pin(wit_files).filter(|p| is_blake3_pin(p))
} Prevention
- Never hand-edit a durable package's meta.json; always rebuild with the SDK.
- Standardize on BLAKE3-hex for all pins and validate at write time.
- Re-publish rather than migrating capsules across hash formats.
When it happens
Trigger: Calling durable_contracts_pin (directly or via refresh_canonical_contracts_from_registry) when any registered capsule's meta.json contains an entry for astrid-contracts.wit whose value is not a valid BLAKE3 hex digest — hand-edited meta.json, a writer that stored a short-hash or sha256 instead of blake3, or corrupt/truncated metadata.
Common situations: Hand-editing or post-processing a durable package's meta.json; migrating capsules built by an older SDK that recorded a different hash format; metadata corruption from an interrupted write or manual copying of the store between machines.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- WASM capsule has no BLAKE3 hash in meta.json
- refusing to seed canonical from a non-content-address contra
- capsule archive already contains {PROVENANCE_FILE}
- durable capsule {} is missing its pinned contracts blob
- durable capsule {} contracts blob digest mismatch
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/694777c5e2294018.
Report an issue: GitHub.