Hmbown/CodeWhale · error
Compaction coverage floor: last-round tool result
Error message
Compaction coverage floor: last-round tool result {id} was dropped; history was not replaced. What it means
The survival contract requires every tool result from the last round to survive compaction. If a replacement history drops a tool result with a given id, the rewrite is rejected. Dropping tool results breaks the tool_use/tool_result pairing providers require.
Solutions
- Preserve the last-round tool results verbatim in the replacement history.
- Fix the rewrite so summarization only applies to rounds before the last one.
- Verify `tool_result_ids` extraction covers all messages of the last round (a missed message hides ids from validation).
- Run the coverage-floor tests to identify the exact drop.
Example fix
// before: tool results summarized away let replacement: Vec<Message> = summarize(last_round); // after: copy tool-result blocks through untouched let replacement: Vec<Message> = keep_tool_blocks(last_round);
Defensive patterns
Strategy: validation
Validate before calling
fn keeps_tool_results(last_round: &[Message], replacement: &[Message]) -> bool {
last_round.iter().flat_map(tool_result_ids)
.all(|id| replacement.iter().any(|m| has_tool_result_id(m, &id)))
} Try / catch
match compaction::apply_replacement(&replacement) {
Err(e) if e.to_string().contains("tool result") => keep_original_history(),
other => other,
} Prevention
- Copy tool_result blocks through verbatim for the last round
- Summarize tool output only in older rounds
- Test rewrites against multi-tool rounds
- Remember providers reject orphaned results — pair with their tool_use
When it happens
Trigger: `validate_last_round_coverage` iterates last-round `tool_result_ids` and finds no message in the replacement containing that tool result id.
Common situations: A rewrite summarizes the last round's tool exchange into prose; a filtering bug drops tool-result blocks; newly added compaction logic prunes 'large' tool outputs including last-round ones.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Compaction coverage floor: a last-round user message was…
- Compaction coverage floor
- Compaction coverage floor: last-round assistant output was…
- Compaction coverage floor: last-round tool call
- Compaction coverage floor: checkpoint receipt was dropped…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/29ed6597c4edfa23.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/compaction/last_round.rs:381
}
// Every user turn in the round, not the first one `find_map` happens to
// reach. `last_round_start` walks back past a toolless tail to the previous
// tool-bearing turn, so the round routinely spans two user messages -- and
// checking only the earliest let a rewrite drop the *latest* one, which is
// the turn this whole contract exists to keep.
for text in last_round.iter().copied().filter_map(user_prompt_text_of) {
if !survives(&text, replacement, user_prompt_text_of) {
anyhow::bail!(
"Compaction coverage floor: a last-round user message was dropped; history was not replaced."
);
}
}
for id in last_round.iter().copied().flat_map(tool_result_ids) {
if !replacement
.iter()
.any(|message| has_tool_result_id(message, &id))
{
anyhow::bail!(
"Compaction coverage floor: last-round tool result {id} was dropped; history was not replaced."
);
}
}
// The call, not just its result. Keeping a tool_result whose tool_use was
// summarized away leaves an orphaned result that providers reject outright.
for id in last_round.iter().copied().flat_map(tool_use_ids) {
if !replacement
.iter()
.any(|message| has_tool_use_id(message, &id))
{
anyhow::bail!(
"Compaction coverage floor: last-round tool call {id} was dropped; history was not replaced."
);
}
}
// Match the assistant's actual output. An existential "some assistant
// message survived" check passed on a replacement whose only assistantView on GitHub (pinned to 73e0f67d83)