Hmbown/CodeWhale · error
Compaction summary response was unusable: a placeholder was
Error message
Compaction summary response was unusable: a placeholder was returned.
What it means
The normalized summary matched a known placeholder or refusal string ('no summary available', 'n/a', 'i cannot provide a summary', ...) at crates/tui/src/compaction.rs:1153, so it is treated as unusable rather than persisted as the session checkpoint.
Source
Thrown at crates/tui/src/compaction.rs:1153
.to_ascii_lowercase();
if normalized.is_empty() {
anyhow::bail!(
"Compaction summary response was unusable: only whitespace or punctuation was returned."
);
}
if matches!(
normalized.as_str(),
"no summary available"
| "summary unavailable"
| "no summary"
| "n/a"
| "na"
| "not available"
| "i cannot provide a summary"
| "i can't provide a summary"
| "unable to provide a summary"
) {
anyhow::bail!("Compaction summary response was unusable: a placeholder was returned.");
}
Ok(())
}
/// Drop the oldest history message before retrying an over-window summary
/// request (Codex parity: `history.remove_first_item()`), plus any tool
/// results the removal orphans — strict providers reject unpaired results.
fn drop_oldest_history_messages(messages: &mut Vec<Message>) {
if messages.len() <= 1 {
return;
}
messages.remove(0);
while messages.len() > 1
&& messages[0]
.content
.iter()
.any(|block| matches!(block, ContentBlock::ToolResult { .. }))
{View on GitHub (pinned to 8880682c63)
Solutions
- Retry - refusals are often stochastic
- Switch or adjust the compaction model (one less prone to refusals)
- If content in the session triggers refusals, compact earlier so the offending context is smaller
- Check whether an intermediary cache is returning a canned response
Defensive patterns
Strategy: fallback
Validate before calling
// Reject known placeholder texts before accepting a summary
const PLACEHOLDERS: [&str; 8] = ["no summary available","summary unavailable","no summary","n/a","na","not available","i cannot provide a summary","i can't provide a summary"];
fn is_placeholder(s: &str) -> bool { PLACEHOLDERS.contains(&s.trim().to_ascii_lowercase().as_str()) } Type guard
fn is_placeholder_summary_error(msg: &str) -> bool {
msg.contains("a placeholder was returned")
} Try / catch
// Fall back to a second model; refusals follow the model, not the input
match compact().await {
Err(e) if is_placeholder_summary_error(&e.to_string()) => compact_with_model(alt_model).await,
r => r,
} Prevention
- Pick compaction models with low refusal rates for code content
- Compact before sessions accumulate content that trips filters
When it happens
Trigger: The summary model refuses the request, a safety filter deflects it, or a gateway returns templated fallback text that happens to match the placeholder list.
Common situations: Refusals triggered by sensitive session content; models that answer literally when they cannot comply; identical canned responses from caching layers.
Related errors
- Compaction summary response was unusable: no text was return
- Compaction summary response was unusable: only whitespace or
- ${name} is unavailable in Workflow scripts: runs must be det
- new Date()/Date() is unavailable in Workflow scripts: runs m
- task(): expected an options object
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/aee4326a6a60dab6.
Report an issue: GitHub.