jdx/mise · error · eyre::Report

task action manifest contains too many predictions

Error message

task action manifest contains too many predictions

What it means

record_action_prediction caps distinct invocation keys per task at MAX_TASK_ACTION_PREDICTIONS (16,384). The cap is enforced only for NEW keys — updating an already-recorded invocation never trips it.

Source

Thrown at crates/mise-cache-core/src/agent.rs:1659

            .get(task)
            .and_then(|state| state.predictions.get(invocation))
            .cloned();
        Ok(AgentResponse::ActionPrediction { prediction })
    }

    fn record_action_prediction(
        &self,
        task: &str,
        prediction: ActionPrediction,
    ) -> Result<AgentResponse> {
        validate_task_identity(task)?;
        validate_action_prediction(&prediction)?;
        let mut tasks = self.task_actions.lock().unwrap();
        let state = tasks.entry(task.to_string()).or_default();
        if !state.predictions.contains_key(&prediction.invocation)
            && state.predictions.len() >= MAX_TASK_ACTION_PREDICTIONS
        {
            bail!("task action manifest contains too many predictions");
        }
        state
            .predictions
            .insert(prediction.invocation.clone(), prediction);
        Ok(AgentResponse::ActionPredictionRecorded)
    }

    fn executable_identity_key(
        &self,
        executable: PathBuf,
        environment: BTreeMap<String, Option<String>>,
    ) -> Result<ExecutableIdentityKey> {
        if !environment
            .keys()
            .all(|name| matches!(name.as_str(), "RUSTUP_HOME" | "RUSTUP_TOOLCHAIN"))
        {
            bail!("executable identity contains an unsupported environment variable");
        }

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Make invocations deterministic so digest keys repeat across runs (stable env, relative paths, no timestamps)
  2. Split the workload across multiple task identities so each stays under the cap
  3. Stop recording predictions for actions that will never repeat — they only consume the per-task budget
Defensive patterns

Strategy: validation

Validate before calling

const MAX_PREDICTIONS: usize = 16 * 1024;
let mut recorded: HashSet<InvocationDigest> = HashSet::new();
fn should_record(recorded: &HashSet<InvocationDigest>, inv: &InvocationDigest) -> bool {
    recorded.contains(inv) || recorded.len() < MAX_PREDICTIONS
}

Prevention

When it happens

Trigger: A task run records more than 16,384 distinct prediction.invocation digests, typically because each run produces unique digests (timestamps, absolute temp paths, random values baked into the invocation).

Common situations: Non-hermetic actions whose invocation digest changes every run (nondeterministic env, random temp dirs); fuzzing or generated-code workloads creating unbounded distinct invocations.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/18d1c11a731bf95e. Report an issue: GitHub.