jdx/mise · error · eyre::Report
cache agent returned an unexpected blob lookup response
Error message
cache agent returned an unexpected blob lookup response
What it means
The blob lookup returned a response variant that does not correspond to FindBlobs at all — e.g. Stored, ActionPrediction, or Hello (src/cache/rustc.rs:508). Responses travel as JSON lines matched positionally on one stream, so a variant mismatch means request/response skew: a version-skewed agent, a desynchronized stream, or a non-mise process answering on MISE_CACHE_SOCKET. This is a wiring error, not corrupted cache data.
Source
Thrown at src/cache/rustc.rs:508
match response {
AgentResponse::Blobs { paths } if paths.len() == digests.len() => paths
.into_iter()
.zip(digests)
.map(|(path, digest)| match path {
Some(path) => Ok(path),
None => bail!("cached rustc action is missing blob {}", digest.hash),
})
.collect(),
AgentResponse::Blobs { .. } => {
bail!("cache agent returned an incomplete blob lookup response")
}
AgentResponse::Blob { path: Some(path) } if digests.len() == 1 => Ok(vec![path]),
AgentResponse::Blob { path: None } if digests.len() == 1 => {
let digest = &digests[0];
bail!("cached rustc action is missing blob {}", digest.hash)
}
AgentResponse::Error { message } => bail!(message),
_ => bail!("cache agent returned an unexpected blob lookup response"),
}
}
fn read_canonical_blob<T>(path: &Path, digest: &CacheDigest, description: &str) -> Result<T>
where
T: DeserializeOwned + Serialize,
{
let bytes = read_verified_blob(path, digest, description)?;
let value = serde_json::from_slice(&bytes)
.wrap_err_with(|| format!("cached {description} is not valid JSON"))?;
if canonical_json(&value)? != bytes {
bail!("cached {description} is not canonical JSON");
}
Ok(value)
}
fn read_verified_blob(path: &Path, digest: &CacheDigest, description: &str) -> Result<Vec<u8>> {
let mut bytes = Vec::new();View on GitHub (pinned to 6f52dcdf99)
Solutions
- Restart the mise session/task so shim and agent share one binary and protocol revision
- Unset inherited MISE_CACHE_* variables before invoking mise so tasks never attach to foreign agents
- Verify only one mise version is installed or active for the session
- If a custom client is involved, align it with AGENT_PROTOCOL_VERSION and the response enum of the running mise
Defensive patterns
Strategy: validation
Validate before calling
# ensure the task is talking to the agent of the session that launched it: test -S "$MISE_CACHE_SOCKET" || echo 'no live cache agent socket — unset MISE_CACHE_* and rerun inside a mise task'
Type guard
fn is_unexpected_lookup(r: &AgentResponse) -> bool {
!matches!(r, AgentResponse::Blobs { .. } | AgentResponse::Blob { .. } | AgentResponse::Error { .. })
} Prevention
- Never inherit MISE_CACHE_* across sessions or machines
- Pin one mise version per CI image and per cache namespace
- If you build custom agent clients, validate the handshake (protocol + agent_version) before sending requests
When it happens
Trigger: MISE_CACHE_SOCKET inherited from a session running another mise build with a different AgentResponse enum shape; a truncated or garbled line deserializing into the wrong variant; a custom tool pretending to be the cache agent.
Common situations: Stale exported MISE_CACHE_* environment in CI images or shell profiles; mixed mise versions on one machine; sockets left behind by crashed sessions being reused.
Related errors
- cache agent returned an incomplete blob lookup response
- cache agent did not return the rustc identity
- cache agent did not store the rustc identity
- cache agent returned an unexpected publish response
- cached {description} is not canonical JSON
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/e3283f4a72998035.
Report an issue: GitHub.