{"record":{"id":"abb066279d8dcace","repo":"deepseek-ai/deepseek-harness","slug":"summarization-produced-no-text-summary-content","errorCode":null,"errorMessage":"summarization produced no text summary content","messagePattern":"summarization produced no text summary content","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/compaction/compaction-basic/src/summarizer.ts","lineNumber":171,"sourceCode":"  const options: GenerateOptions = {\n    provider: target.provider,\n    model: target.model,\n    messages,\n    ...input.system === undefined ? {} : { system: input.system },\n    ...input.tools === undefined ? {} : { tools: [...input.tools] },\n    maxTokens: config.maxTokens,\n    sessionId: agent.session.id,\n    purpose: 'compaction',\n    ...signal === undefined ? {} : { signal },\n  }\n  for await (const chunk of ctx.llm.stream(options)) assembler.push(chunk)\n  const error = finishError(assembler.finish)\n  if (error !== undefined) throw error\n\n  const rawOutput = assembler.blocks()\n  const summary = summaryText(rawOutput)\n  if (!summary.some(block => block.text.trim().length > 0)) {\n    throw new Error('summarization produced no text summary content')\n  }\n  return {\n    summary,\n    rawOutput,\n    llmStreamCall: true,\n    provider: options.provider,\n    model: options.model,\n    maxTokens: config.maxTokens,\n    ...(assembler.usage === undefined ? {} : { usage: assembler.usage }),\n  }\n}\n\n/**\n * Wrap raw summary blocks in the durable checkpoint framing.\n * @param summary - safe text-only model output.\n * @returns content for the synthesized replacement user message.\n */\nexport function frameSummary(summary: readonly ContentBlock[]): ContentBlock[] {","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/compaction/compaction-basic/src/summarizer.ts#L153-L189","documentation":"The summarization stream finished without a finish error, but after the safe-text projection no text block with non-whitespace content remains — the model returned only reasoning or tool-call blocks, or empty text. Only returned text may enter the checkpoint, so the transaction fails rather than write an empty checkpoint (image output fails earlier with UNSUPPORTED_CONTENT).","triggerScenarios":"A tool-forward model answers the compaction instruction with a tool-call despite the 'output only the checkpoint text' rule; a reasoning model whose filtered visible output is empty; a provider returning an empty completion under load.","commonSituations":"Summarization routed to an agent-tuned local model; intermittent empty completions from the provider; instruction-following regressions after a model swap.","solutions":["Route summarization to a plain instruction-following text model via summarizationProvider/summarizationModel","Retry once — empty completions are often transient","Inspect the provider response for the purpose:'compaction' call to see what the model actually returned","If it persists, override the protected summarize() hook with a deterministic summarizer"],"exampleFix":"// before: summarizer routed to a tool-forward agent model\nctx.plugin(BasicCompactionEngine, {\n  summarizationProvider: 'local',\n  summarizationModel: 'agent-tuned-model',\n})\n\n// after: plain text model for the auxiliary call\nctx.plugin(BasicCompactionEngine, {\n  summarizationProvider: 'deepseek',\n  summarizationModel: 'deepseek-chat',\n})","handlingStrategy":"retry","validationCode":null,"typeGuard":"const isEmptySummary = (error: unknown): error is Error =>\n  error instanceof Error && error.message === 'summarization produced no text summary content'","tryCatchPattern":"for (let attempt = 0; ; attempt += 1) {\n  try {\n    return await ctx.compaction.compactNow(agent, signal)\n  } catch (error) {\n    if (isEmptySummary(error) && attempt < 1) continue // empty completions are often transient\n    throw error\n  }\n}","preventionTips":["Route summarization to a plain instruction-following text model, not an agent-tuned one","Retry once on empty output before treating it as a configuration problem","If a model repeatedly answers the compaction instruction with tool calls or empty text, override the summarize() hook or change the summarization model"],"tags":["compaction","summarization","llm-output","empty-response"],"backgroundTag":"empty-llm-response","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}