jdx/mise · error · eyre::Report

cache agent did not return an action prediction response

Error message

cache agent did not return an action prediction response

What it means

mise's rustc wrapper cache talks to a background cache agent over a socket (MISE_CACHE_SOCKET) with a request/response protocol. When the wrapper sends FindActionPrediction, it expects at least one AgentResponse back; an empty response vector violates the protocol and bails (src/cache/rustc.rs:134).

Source

Thrown at src/cache/rustc.rs:134

}

fn restore_predicted_result(
    rustc: &OsStr,
    invocation: &RustcInvocation,
    outputs: &RustcOutputs,
    working_dir: &Path,
    restore_outputs: bool,
) -> Result<Option<CachedCompilation>> {
    let task = std::env::var(session::TASK_ENV)
        .wrap_err_with(|| format!("{} is not set", session::TASK_ENV))?;
    let mut context = base_action_context(rustc, working_dir)?;
    let invocation_digest = invocation.invocation_digest(&context)?;
    let responses = session::request_agent(&[AgentRequest::FindActionPrediction {
        task,
        invocation: invocation_digest.clone(),
    }])?;
    let Some(response) = responses.into_iter().next() else {
        bail!("cache agent did not return an action prediction response");
    };
    let prediction = match response {
        AgentResponse::ActionPrediction {
            prediction: Some(prediction),
        } => prediction,
        AgentResponse::ActionPrediction { prediction: None } => return Ok(None),
        AgentResponse::Error { message } => bail!(message),
        _ => bail!("cache agent returned an unexpected action prediction response"),
    };
    if prediction.adapter != "rustc" || prediction.invocation != invocation_digest {
        bail!("cache agent returned an incompatible rustc action prediction");
    }
    let input_prediction: RustcInputPrediction = serde_json::from_str(&prediction.payload)?;
    if String::from_utf8(canonical_json(&input_prediction)?)? != prediction.payload {
        bail!("cache agent returned a non-canonical rustc action prediction");
    }
    let discovered = input_prediction.discover(working_dir, &context.path_mappings)?;
    discovered.clone().apply_to(&mut context)?;

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Restart the build/session so a fresh cache agent starts with matching env (MISE_CACHE_TASK, MISE_CACHE_SOCKET)
  2. Upgrade mise so the wrapper and agent come from the same binary/version
  3. If it persists, disable the rustc cache for the session (remove the rustc wrapper from RUSTC_WRAPPER / mise settings) and report the protocol violation upstream

Example fix

# before: stale agent env
export RUSTC_WRAPPER=$HOME/.local/share/mise/rustc-wrapper

# after: start clean
unset MISE_CACHE_SOCKET MISE_CACHE_TASK MISE_CACHE_STAGING_DIR
cargo clean -p mycrate && cargo build
Defensive patterns

Strategy: retry

Try / catch

# Bash: treat cache-agent protocol failures as transient
cargo build 2>err.log || true
if grep -q 'cache agent did not return' err.log; then
  unset MISE_CACHE_SOCKET MISE_CACHE_TASK MISE_CACHE_STAGING_DIR
  cargo build   # fresh agent, same inputs
fi

Prevention

When it happens

Trigger: The cache agent daemon returns zero responses for a one-request batch — a crashed/restarted agent mid-request, a version-skewed agent speaking an older protocol, or a socket race where the wrapper connected to a dying agent.

Common situations: Running builds while `mise` was upgraded underneath a live agent; agent killed by OOM or manually during a compile; stale MISE_CACHE_* env vars pointing at an old socket after a daemon restart.

Related errors


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