jdx/mise · error · eyre::Report
cannot publish an action result with a missing blob
Error message
cannot publish an action result with a missing blob
What it means
`LocalActionCache::store` requires every digest referenced by the result - the action digest itself plus optional `metadata` and `output_root` - to already exist and verify in the local CAS before the index entry is published. Publishing without the blobs would create dangling references. The crate's own test (`publishes_action_results_after_referenced_blobs`) documents the required order: blobs first, action result second.
Source
Thrown at crates/mise-cache-core/src/local.rs:215
}
Ok(Some(result))
}
/// Atomically publish an action result after validating all referenced objects.
pub fn store(&self, result: &RemoteActionResult) -> Result<PathBuf> {
if result.version != 1 {
bail!("unsupported local action result version");
}
for digest in [
Some(&result.action),
result.metadata.as_ref(),
result.output_root.as_ref(),
]
.into_iter()
.flatten()
{
if self.cas.find(digest)?.is_none() {
bail!("cannot publish an action result with a missing blob");
}
}
let destination = self.path_for(&result.action)?;
let replace_invalid = match self.find(&result.action) {
Ok(Some(existing)) => {
if existing == *result {
return Ok(destination);
}
bail!("local action key already has a different result");
}
Ok(None) => false,
Err(_) => true,
};
let parent = destination
.parent()
.expect("action-result path has a parent");
fs::create_dir_all(parent)?;
let mut temporary = tempfile::NamedTempFile::new_in(parent)?;View on GitHub (pinned to 6f52dcdf99)
Solutions
- Store all referenced blobs first: `cas.store_bytes(&result.action, ...)`, plus metadata and output_root when present, then `actions.store(&result)`.
- When publishing downloaded results, materialize blobs into the local CAS before storing the action entry.
- As a pre-check, iterate `[result.action, result.metadata, result.output_root]` and confirm `cas.find` returns each.
Example fix
// before
actions.store(&result)?; // bails: referenced blobs missing
// after
cas.store_bytes(&result.action, &manifest_bytes)?;
if let Some(d) = &result.metadata { cas.store_bytes(d, &metadata_bytes)?; }
if let Some(d) = &result.output_root { cas.store_file(d, &output_root_dir)?; }
actions.store(&result)?; Defensive patterns
Strategy: validation
Validate before calling
let refs = [Some(&result.action), result.metadata.as_ref(), result.output_root.as_ref()]
.into_iter()
.flatten();
for digest in refs {
if cas.find(digest)?.is_none() {
cas.store_bytes(digest, &materialize(digest).await?)?;
}
}
actions.store(&result)?; Prevention
- Always publish blobs before action results; the action manifest blob is required too.
- Centralize the publish sequence in one function so the order cannot be inverted.
- On download paths, materialize all referenced blobs into the local CAS before storing the index entry.
When it happens
Trigger: Calling `actions.store(&result)` before `cas.store_bytes`/`store_file` for the action digest, the metadata digest, or the output-root digest. A common miss is forgetting that the action key blob itself must be present in the CAS, not just the outputs.
Common situations: Publishing only outputs and skipping the action manifest blob; download flows persisting an action result before materializing its blobs into the local CAS.
Related errors
- local CAS blob failed digest verification: {}
- bytes do not match the declared CAS digest
- staged blob does not match the declared CAS digest
- staged blob size does not match the declared CAS digest
- local action keys must use blake3
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/21fb8e8b3986d094.
Report an issue: GitHub.