{"record":{"id":"2f25f5c8e7e79b8c","repo":"siyuan-note/siyuan","slug":"agent-compaction-summary-is-empty","errorCode":null,"errorMessage":"agent compaction summary is empty","messagePattern":"agent compaction summary is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/compaction.go","lineNumber":42,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sashabaranov/go-openai\"\n\t\"github.com/siyuan-note/siyuan/kernel/util\"\n)\n\nconst (\n\tcompactionVersion          = 1\n\tcompactionSummaryMinTokens = 256\n\tcompactionSummaryMaxTokens = 2048\n\tcompactionSummaryOverhead  = 128\n)\n\nvar errContextCannotBeCompacted = errors.New(\"agent context cannot be compacted enough\")\nvar errCompactionSummaryEmpty = errors.New(\"agent compaction summary is empty\")\n\nfunc isContextOverflow(err error) bool {\n\tmsg := err.Error()\n\treturn strings.Contains(msg, \"context_length_exceeded\") ||\n\t\tstrings.Contains(msg, \"maximum context length\") ||\n\t\tstrings.Contains(msg, \"reduce the length\") ||\n\t\tstrings.Contains(msg, \"too many tokens\") ||\n\t\tstrings.Contains(msg, \"input is too long\") ||\n\t\tstrings.Contains(msg, \"exceeds the context window\") ||\n\t\tstrings.Contains(msg, \"超出上下文\") ||\n\t\tstrings.Contains(msg, \"上下文长度\")\n}\n\nfunc cloneRuntimeCompaction(compaction *runtimeCompaction) *runtimeCompaction {\n\tif compaction == nil {\n\t\treturn nil\n\t}\n\tcloned := *compaction","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/agent/compaction.go#L24-L60","documentation":"errCompactionSummaryEmpty is returned by createProtocolCompactionSummary when the streaming summary request completed but produced no non-whitespace summary text after trimming. An empty summary would corrupt the compacted context, so the compaction aborts with this sentinel error.","triggerScenarios":"The summary model streams a response whose accumulated choice delta content is empty or whitespace-only (e.g. the model emits only reasoning/tool tokens, or returns an empty completion) — checked at compaction.go:240 before returning the summary.","commonSituations":"A model that puts output in a non-content field (e.g. reasoning models with empty delta.Content); a misconfigured summary prompt that the model answers with nothing; a provider hiccup returning empty choices; very low max completion tokens truncating output to nothing.","solutions":["Retry the compaction — transient empty completions often succeed on a second attempt","Check compactionSummaryMaxTokens (2048) is not set too low in configuration and that the summary model supports content output","Switch the summary/compaction model to a standard chat model that returns delta.Content","Review the summary prompt for constraints that may cause the model to produce no text"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"summary, err := createCompactionSummary(ctx, ...)\nif errors.Is(err, errCompactionSummaryEmpty) { summary, err = createCompactionSummary(ctx, ...) } // retry once with a different model/prompt if still empty","preventionTips":["Use a standard chat completion model for summarization (returns delta.Content)","Ensure the summary prompt explicitly asks for a prose summary","Set adequate max completion tokens for the summary request"],"tags":["agent","compaction","empty-response","llm"],"backgroundTag":"empty-response-body","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}