jdx/mise · error · eyre::Report
cannot record a hit for a missing action result
Error message
cannot record a hit for a missing action result
What it means
record_action_hit requires the action result to exist locally (actions.find) or to still sit in pending_remote_actions (speculative prefetch results awaiting first use). If neither holds, the client is claiming a hit for an action whose result the agent never served or prefetched, which is a protocol violation.
Source
Thrown at crates/mise-cache-core/src/agent.rs:1612
) -> Result<Option<RemoteActionResult>> {
self.stats
.remote_action_lookups
.fetch_add(1, Ordering::Relaxed);
let _timer = AtomicDurationTimer::start(&self.stats.remote_action_lookup_duration_ns);
remote.get_action_result(action).await
}
fn record_action_hit(
&self,
action: &CacheDigest,
restore: RestoreStats,
) -> Result<AgentResponse> {
if self.actions.find(action)?.is_none() {
let pending = self.pending_remote_actions.lock().unwrap().remove(action);
if let Some(result) = pending {
self.actions.store(&result)?;
} else {
bail!("cannot record a hit for a missing action result");
}
}
self.record_restore(restore);
self.stats.hits.fetch_add(1, Ordering::Relaxed);
Ok(AgentResponse::ActionHitRecorded)
}
fn record_restore(&self, restore: RestoreStats) {
self.record_materialization(restore);
atomic_saturating_add(&self.stats.restored_output_files, restore.output_files);
atomic_saturating_add(&self.stats.restored_output_bytes, restore.output_bytes);
}
fn record_materialization(&self, restore: RestoreStats) {
atomic_saturating_add(&self.stats.materialization_duration_ns, restore.duration_ns);
}
fn find_action_prediction(View on GitHub (pinned to 6f52dcdf99)
Solutions
- Only record a hit for digests previously returned by the agent (lookup or prefetch responses)
- De-duplicate RecordActionHit requests client-side — never send the same digest twice
- If pruning races are expected, re-run the lookup path instead of blindly recording a hit
Defensive patterns
Strategy: validation
Validate before calling
// Track served digests client-side and only record hits for them
let mut served: HashSet<[u8; 32]> = HashSet::new();
if let Some(hit) = agent_lookup(&agent, &digest).await? {
served.insert(digest);
// ... later ...
if served.contains(&digest) {
agent.record_action_hit(&digest, restore_stats).await?;
}
} Prevention
- Never send RecordActionHit speculatively — only for digests actually returned by the agent
- De-duplicate hit records client-side (one per digest)
- Treat this error as a client protocol bug, not an environment issue
When it happens
Trigger: A client sends RecordActionHit for a digest it never received from a lookup/prefetch response; the same digest is recorded twice after the pending entry was consumed; the local cache entry was pruned between serve and record.
Common situations: Hand-rolled clients speculatively reporting hits; concurrent cache pruning racing a hit record; duplicated request replay in client logic.
Related errors
- the first agent request must be hello
- task action manifest baseline was not loaded
- task action manifest is not canonical JSON
- remote task action manifest changed too frequently
- remote rustc action metadata is invalid
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/a551d53133f3b5ea.
Report an issue: GitHub.