Hmbown/CodeWhale · error
Compaction summary response was unusable: no text was return
Error message
Compaction summary response was unusable: no text was returned.
What it means
validate_compaction_summary (crates/tui/src/compaction.rs:1125) rejects a summary that is empty after trim. The compaction path prefers failing - and keeping the full history - over replacing the session with an empty continuation checkpoint.
Source
Thrown at crates/tui/src/compaction.rs:1125
let mut prompt = format!(
"The previous handoff response was empty or a placeholder. Return a substantive factual \
continuation handoff. State the user objective, completed and current work, hard constraints, verified \
evidence, unresolved failures, and the single next action. Do not refuse, call tools, discuss \
checkpoint machinery, or return a placeholder. {COMPACTION_LANGUAGE_CONTRACT}"
);
if let Some(focus) = focus.map(str::trim).filter(|focus| !focus.is_empty()) {
let _ = write!(
prompt,
"\n\nThe user asked this compaction to focus on: {focus}"
);
}
prompt
}
fn validate_compaction_summary(summary: &str) -> Result<()> {
let trimmed = summary.trim();
if trimmed.is_empty() {
anyhow::bail!("Compaction summary response was unusable: no text was returned.");
}
// Strip every non-word edge, not just ASCII punctuation. Providers can
// return visually non-empty Unicode punctuation or emoji-only payloads;
// neither is a usable continuation checkpoint. `is_alphanumeric` keeps
// this language-neutral for CJK and other scripts without imposing a
// prose-length heuristic.
let normalized = trimmed
.trim_matches(|ch: char| !ch.is_alphanumeric())
.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"View on GitHub (pinned to 8880682c63)
Solutions
- Retry compaction - a single empty response is usually stochastic
- Use a model with stronger instruction-following for the summary step
- Check the provider/gateway for content filtering or blocklists that empty responses
- Confirm the compaction model actually supports plain text output for the configured response format
Defensive patterns
Strategy: try-catch
Type guard
fn is_unusable_summary(msg: &str) -> bool {
msg.contains("Compaction summary response was unusable")
} Try / catch
// Retry once with a different model, then surface: never persist an empty checkpoint
match compact().await {
Err(e) if is_unusable_summary(&e.to_string()) => compact_with_model(fallback_model).await,
r => r,
} Prevention
- Use instruction-following models for summarization
- Watch for content filters that blank responses
- Rely on the failure: history is preserved, so retrying is always safe
When it happens
Trigger: The summary model returns an empty assistant message (tool-call-only completion, response_format forcing empty output) or a gateway strips the content block.
Common situations: Small models with weak instruction-following asked to summarize very long histories; providers under content filtering that blank responses; misconfigured gateways.
Related errors
- Compaction summary response was unusable: only whitespace or
- speech synthesis requires provider 'xiaomi-mimo' (current: {
- Compaction summary response was unusable: a placeholder was
- Compaction summary response incomplete: provider stop reason
- {name}.context_window must be greater than 0
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/cee0ae934da6baf5.
Report an issue: GitHub.