jdx/mise · error · eyre::Report

compiler environment input changed: {name}

Error message

compiler environment input changed: {name}

What it means

The cache records compiler-relevant environment variables as part of the invocation identity. On replay, verify_environment re-reads each recorded variable and requires the exact same value (including unset-vs-empty); any difference bails with 'compiler environment input changed: NAME' (src/cache/rustc.rs:259). This is a correctness guard: reusing cached outputs under a changed env would be wrong.

Source

Thrown at src/cache/rustc.rs:259

            _ => bail!("cache agent returned an unexpected prediction response"),
        }
    })();
    if let Err(error) = result {
        eprintln!("mise rustc cache warning: action prediction was not recorded: {error:#}");
    }
}

fn verify_environment(environment: &BTreeMap<String, Option<String>>) -> Result<()> {
    for (name, expected) in environment {
        let actual = std::env::var_os(name)
            .map(|value| {
                value.into_string().map_err(|_| {
                    eyre::eyre!("compiler environment input is not valid UTF-8: {name}")
                })
            })
            .transpose()?;
        if &actual != expected {
            bail!("compiler environment input changed: {name}");
        }
    }
    Ok(())
}

fn restore_result(
    action: &RustcAction,
    outputs: &RustcOutputs,
    discovered: &DiscoveredInputs,
    restore_outputs: bool,
) -> Result<Option<CachedCompilation>> {
    let responses = session::request_agent(&[AgentRequest::FindActionResult {
        action: action.digest.clone(),
    }])?;
    let Some(response) = responses.into_iter().next() else {
        bail!("cache agent did not return an action lookup response");
    };
    let result = match response {

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Make the environment deterministic: export the same RUSTFLAGS/CARGO_*/CC values in every build that shares the cache
  2. Re-run the build once with the new env so a fresh entry is recorded for it
  3. Don't share one cache agent/store across environments that intentionally differ in these variables

Example fix

# before: one shell recorded with default flags
export RUSTFLAGS=""
# later shell replays with
export RUSTFLAGS="-C target-cpu=native"

# after: keep env identical across cached builds
export RUSTFLAGS="-C target-cpu=native"  # used for both record and replay
Defensive patterns

Strategy: validation

Validate before calling

# Rust: snapshot the recorded env and diff before replaying
fn env_matches(recorded: &std::collections::BTreeMap<String, Option<String>>) -> Result<(), String> {
    for (k, expected) in recorded {
        let actual = std::env::var_os(k).map(|v| v.to_string_lossy().into_owned());
        if actual.as_ref().map(|s| Some(s.clone())) != Some(expected.clone()) {
            return Err(format!("compiler environment input changed: {k}"));
        }
    }
    Ok(())
}

Prevention

When it happens

Trigger: Building with a recorded cache hit while an environment variable the compilation captured (e.g. RUSTFLAGS, CARGO_*, CC, SDKROOT) differs from when the entry was recorded — set in one shell and not another, toggled by CI matrix jobs, or changed by a direnv/config update.

Common situations: CI jobs sharing a cache but differing in RUSTFLAGS or target env; developer shells with per-project .envrc exports; RUSTC_WRAPPER/toolchain updates changing recorded env between record and replay.

Related errors


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