jdx/mise · error

local task cache manifest does not match remote action

Error message

local task cache manifest does not match remote action

What it means

During commit, the CacheManifest's embedded key did not match the remote cache key the entry is being written under. The manifest is the authoritative record of what the entry contains; a mismatch means the caller is associating a manifest from a different action with this key, which would serve wrong cached results.

Source

Thrown at src/task/task_cache_store.rs:453

        })
    }

    async fn commit(
        &self,
        key: &str,
        action: &[u8],
        write: &TaskCacheStoreWrite,
        manifest: &[u8],
        has_artifact: bool,
    ) -> Result<()> {
        validate_remote_key(key)?;
        let action_digest = CacheDigest::blake3(action);
        if action_digest.hash != key {
            bail!("remote cache action bytes do not match cache key");
        }
        let manifest: CacheManifest = serde_json::from_slice(manifest)?;
        if manifest.key != key {
            bail!("local task cache manifest does not match remote action");
        }
        let metadata = canonical_json(&serde_json::to_value(
            RemoteClientMetadata::from_manifest(&manifest),
        )?)?;
        let mut uploads = vec![
            BlobUpload {
                digest: action_digest.clone(),
                source: BlobSource::Bytes(action.to_vec()),
            },
            BlobUpload {
                digest: CacheDigest::blake3(&metadata),
                source: BlobSource::Bytes(metadata),
            },
        ];
        let metadata = uploads[1].digest.clone();
        let output_root = if has_artifact {
            let (root, mut artifact_uploads) =
                archive_to_cas(write.artifact_path(), &self.staging_dir)?;

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Rebuild the CacheManifest from the same action/state used to derive the key, set manifest.key = key, and re-serialize immediately before commit
  2. Verify each (key, action, manifest) triple is built from one run — don't zip mismatched arrays in batch commits
  3. Deserialize the manifest and compare its key to the intended key before calling commit to fail early
  4. Clear stale manifests and regenerate rather than reusing previously serialized bytes

Example fix

// before
let manifest_bytes = old_manifest_bytes; // key from previous run
store.commit(&key, &action, &manifest_bytes, true)?;
// after
let mut manifest = build_manifest(&action);
manifest.key = key;
store.commit(&key, &action, &serde_json::to_vec(&manifest)?, true)?;
Defensive patterns

Strategy: validation

Validate before calling

let manifest: CacheManifest = serde_json::from_slice(&manifest_bytes)?;
anyhow::ensure!(manifest.key == key, "manifest key {} != commit key {}", manifest.key, key);
store.commit(&key, &action, &manifest_bytes, has_artifact)?;

Try / catch

match store.commit(&key, &action, &manifest_bytes, has_artifact).await {
    Err(e) if e.to_string().contains("manifest does not match remote action") => {
        let mut m = rebuild_manifest(&action);
        m.key = key;
        store.commit(&key, &action, &serde_json::to_vec(&m)?, has_artifact).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling commit() passing a manifest serialized for one action/key together with a key (and action bytes) from another — e.g. re-serializing the manifest after changing its key field, mixing up manifests when committing several entries in a loop, or loading a manifest from disk that belongs to a different task.

Common situations: Batch publish scripts that zip keys[] with manifests[] from different task runs; retry logic that rebuilds the action (new key) but reuses the old manifest bytes; copying manifest files between cache entries.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/b6f35bc83806603e. Report an issue: GitHub.