astrid-runtime/astrid · error
WASM catalog entry has no readable bytes: bin/{hash}.wasm
Error message
WASM catalog entry has no readable bytes: bin/{hash}.wasm What it means
Raised when read_range succeeded but returned None (no bytes) even though the descriptor exists: the catalog entry bin/{hash}.wasm has metadata but zero readable content. read_catalog_wasm surfaces this so catalog_wasm_hash fails loudly instead of hashing empty bytes.
Source
Thrown at crates/astrid-capsule-install/src/wasm.rs:123
/// Read one verified executable from the system-owned content catalog.
pub(crate) fn read_catalog_wasm(
storage: &RuntimePrincipalStore,
hash: &str,
) -> anyhow::Result<Vec<u8>> {
let name = ContentName::new(format!("bin/{hash}.wasm"))
.context("construct system WASM catalog name")?;
let descriptor = storage
.content()
.describe(&StateOwner::System, &name)
.map_err(|error| anyhow::anyhow!(error))
.context("describe WASM in system catalog")?
.ok_or_else(|| anyhow::anyhow!("WASM catalog entry is missing: bin/{hash}.wasm"))?;
storage
.content()
.read_range(&StateOwner::System, &name, 0, descriptor.logical_bytes())
.map_err(|error| anyhow::anyhow!(error))
.context("read WASM from system catalog")?
.ok_or_else(|| anyhow::anyhow!("WASM catalog entry has no readable bytes: bin/{hash}.wasm"))
}
/// Verify that the system catalog entry for `expected` exists and hashes to
/// its content-addressed name.
pub fn catalog_wasm_hash(
storage: &RuntimePrincipalStore,
expected: &str,
) -> anyhow::Result<String> {
let actual = blake3::hash(&read_catalog_wasm(storage, expected)?)
.to_hex()
.to_string();
anyhow::ensure!(
actual == expected,
"installed WASM integrity check failed: expected BLAKE3 {expected}, got {actual}"
);
Ok(actual)
}
View on GitHub (pinned to affd8760f4)
Solutions
- Re-run the install so put_streaming_batch republishes the full WASM bytes into the catalog
- Check the WASM source file is non-empty before install (a 0-byte artifact produces an empty entry)
- Repair or reinitialize a corrupted content store and republish all catalog entries
- If using a custom content store, fix read_range so it returns an error rather than None for readable-data loss
Defensive patterns
Strategy: validation
Validate before calling
// reject empty artifacts before publishing
if wasm_bytes.is_empty() {
anyhow::bail!("refusing to publish 0-byte WASM artifact");
} Try / catch
match catalog_wasm_hash(&storage, &expected) {
Err(e) if e.to_string().contains("no readable bytes") => {
// entry exists but is empty: force a full republish
storage.content().delete(&StateOwner::System, &name)?;
republish_wasm(&storage, &source_bytes)?;
catalog_wasm_hash(&storage, &expected)
}
other => other,
} Prevention
- Validate the source .wasm is non-empty before install
- Never kill an install during put_streaming_batch; crash-safety requires a clean republish
- Test custom content-store backends to ensure they never return Ok(None) for existing descriptors
When it happens
Trigger: catalog_wasm_hash -> read_catalog_wasm: describe() returns a descriptor, read_range(&StateOwner::System, &name, 0, descriptor.logical_bytes()) completes with Ok(None) — the entry exists in the index but holds no readable bytes.
Common situations: Interrupted streaming ingest that recorded the descriptor but not the data; empty/truncated blob files after a crash; storage backend returning empty reads silently (misbehaving custom backend); zero-byte WASM file published.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- publish WASM into the system content catalog
- describe WASM in system catalog
- WASM catalog entry is missing: bin/{hash}.wasm
- read WASM from system catalog
- WASM capsule has no BLAKE3 hash in meta.json
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/da7f2e0f6008eedd.
Report an issue: GitHub.