jdx/mise · error · eyre::Report

cached rustc action descriptor does not match the invocation

Error message

cached rustc action descriptor does not match the invocation

What it means

The wrapper fetches the action-descriptor blob and requires it to be byte-identical to the action it just recomputed for this invocation. Equal digests with different bytes means non-deterministic serialization or a colliding/corrupted blob — either way the entry cannot be trusted and the wrapper bails (src/cache/rustc.rs:301).

Source

Thrown at src/cache/rustc.rs:301

        _ => bail!("cache agent returned an unexpected action lookup response"),
    };
    if result.version != 1 || result.action != action.digest {
        bail!("cached rustc action result has an invalid identity");
    }
    let metadata_digest = result
        .metadata
        .ok_or_else(|| eyre::eyre!("cached rustc action result has no metadata"))?;
    let output_root_digest = result
        .output_root
        .ok_or_else(|| eyre::eyre!("cached rustc action result has no output root"))?;
    let roots = find_blobs(&[
        action.digest.clone(),
        metadata_digest.clone(),
        output_root_digest.clone(),
    ])?;
    let cached_action = read_verified_blob(&roots[0], &action.digest, "action descriptor")?;
    if cached_action != action.bytes {
        bail!("cached rustc action descriptor does not match the invocation");
    }
    let metadata: RustcMetadata =
        read_canonical_blob(&roots[1], &metadata_digest, "rustc metadata")?;
    if metadata.version != 1 || metadata.kind != "rustc" {
        bail!("cached rustc metadata is unsupported");
    }
    let directory: CacheDirectory =
        read_canonical_blob(&roots[2], &output_root_digest, "output directory")?;
    let files = validated_outputs(directory, outputs)?;
    let cached_outputs = files
        .iter()
        .map(|(node, destination)| CachedOutput {
            path: destination.clone(),
            digest: node.digest.clone(),
            mode: node.mode,
        })
        .collect();
    let restored_output_files = files.len().try_into().unwrap_or(u64::MAX);

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Clear the blob/result cache and rebuild so descriptors are re-recorded with the current serializer
  2. Confirm only one mise version is in use for agent and wrapper
  3. If it recurs on a single version, capture the mismatch and report it — deterministic serialization is a mise invariant
Defensive patterns

Strategy: fallback

Try / catch

# Descriptor mismatch => corrupted/stale store: clear blobs, rebuild
if grep -q 'action descriptor does not match the invocation' build.log; then
  rm -rf "$MISE_CACHE_STAGING_DIR"; cargo build
fi

Prevention

When it happens

Trigger: Action serialization changed between the recording and replaying mise builds (same digest recipe but different byte layout), or the blob store returned corrupted/mismatched bytes for the digest.

Common situations: mise upgrade altering canonical action bytes; disk corruption or partial writes in the blob store; two mise versions sharing one agent.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/0937c72890db5359. Report an issue: GitHub.