{"record":{"id":"ac32d939fe9beb94","repo":"zed-industries/zed","slug":"compaction-produced-an-empty-summary","errorCode":null,"errorMessage":"Compaction produced an empty summary","messagePattern":"Compaction produced an empty summary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/agent/src/thread.rs","lineNumber":3210,"sourceCode":"                | LanguageModelCompletionEvent::Thinking { .. }\n                | LanguageModelCompletionEvent::RedactedThinking { .. }\n                | LanguageModelCompletionEvent::ReasoningDetails(_)\n                | LanguageModelCompletionEvent::ToolUse(_)\n                | LanguageModelCompletionEvent::ToolUseJsonParseError { .. }\n                | LanguageModelCompletionEvent::StartMessage { .. }\n                | LanguageModelCompletionEvent::Compaction(_) => {}\n            }\n        }\n\n        if *cancellation_rx.borrow() {\n            log::debug!(\"Compaction cancelled after summarizing\");\n            return Ok(ControlFlow::Break(()));\n        }\n\n        let summary = summary.trim().to_string();\n        if summary.is_empty() {\n            log::warn!(\"Compaction produced an empty summary\");\n            return Err(anyhow::anyhow!(\"Compaction produced an empty summary\"));\n        }\n\n        log::debug!(\"Compaction succeeded:\\n{summary}\");\n        event_stream.update_context_compaction_status(\n            compaction_id,\n            acp_thread::ContextCompactionStatus::Completed,\n        );\n\n        this.update(cx, |this, cx| {\n            let compaction = Arc::new(Message::Compaction(CompactionInfo::Summary(summary.into())));\n            match insertion {\n                CompactionInsertion::Auto { insertion_ix } => {\n                    if insertion_ix <= this.messages.len() {\n                        this.messages.insert(insertion_ix, compaction);\n                    } else {\n                        this.messages.push(compaction);\n                    }\n                }","sourceCodeStart":3192,"sourceCodeEnd":3228,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/agent/src/thread.rs#L3192-L3228","documentation":"After a compaction stream finishes, the accumulated summary is trimmed; if the result is empty, the compaction task returns this error instead of replacing the thread history with an empty summary. It protects the transcript from data loss when the model produced no usable summary text.","triggerScenarios":"The compaction model streams only whitespace or no text at all; the summary content arrived only in event variants the accumulator ignores; or the stream glitched and completed without emitting summary content while the cancellation flag was not set.","commonSituations":"A weak or misbehaving compaction model returning empty output; a provider outage mid-stream yielding a completed-but-empty response; rare cancellation races where the check at the top passed but no content was ever accumulated.","solutions":["Retry the compaction; transient empty outputs usually do not repeat","Switch to a stronger or different compaction model in settings","Check provider status and network stability if empty summaries recur","If it recurs on one thread, reduce context pressure (manually trim older messages) before compacting again"],"exampleFix":"// before\nlet events = thread.update(cx, |t, cx| t.compact(id, cx))?;\nconsume(events).await?;\n\n// after: retry once on empty-summary failures\nfor attempt in 0..2 {\n    let events = thread.update(cx, |t, cx| t.compact(id, cx))?;\n    match consume(events).await {\n        Ok(()) => break,\n        Err(err) if err.to_string().contains(\"empty summary\") && attempt == 0 => continue,\n        Err(err) => return Err(err),\n    }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in 0..2 {\n    match compact_thread(thread, id).await {\n        Ok(()) => break,\n        Err(err) if err.to_string().contains(\"empty summary\") && attempt + 1 < 2 => {\n            continue; // transient empty output: retry compaction once\n        }\n        Err(err) => return Err(err),\n    }\n}","preventionTips":["Prefer a stable, capable compaction model over weak or experimental ones","Avoid compacting during known provider incidents or unstable networks","Treat 'empty summary' as retryable, not as corruption of the thread","Keep manual trim available as a fallback when compaction repeatedly fails"],"tags":["rust","agent","compaction","empty-response","language-model"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}