thedotmack/claude-mem · warning
Empty summary response, leaving queue intact
Error message
Empty ${this.providerName} summary response, leaving queue intact What it means
Same guard as the observation path but for summary messages: when the summary response has no content and forwardEmptyMessageResponse is false, processAgentResponse is skipped and the queued summary request is left intact. It stops empty summaries from wiping or corrupting session state.
Solutions
- Check the summary model and prompt; try a model that reliably returns content.
- Enable forwardEmptyMessageResponse if empty summaries are acceptable to forward.
- Inspect the upstream finish reason / error fields in the raw response.
- The queue entry remains intact — re-run the summary after fixing the upstream cause.
Example fix
// before
summaryConfig = { model: "min-model" };
// after
summaryConfig = { model: "gpt-4o-mini" }; // model that returns content reliably Defensive patterns
Strategy: fallback
Validate before calling
if (!summaryResponse?.content) {
// leave summary queue intact and retry later
} Type guard
const hasContent = (r: { content?: string | null }): r is { content: string } =>
typeof r.content === 'string' && r.content.trim().length > 0; Try / catch
if (!hasContent(summaryResponse) && !provider.forwardEmptyMessageResponse) {
logger.warn('summary empty, will retry');
} Prevention
- Use a proven model for summarization
- Keep summary prompts within the model's context window
- Monitor for repeated empty summaries indicating upstream degradation
When it happens
Trigger: In processSummaryMessage (called from runMessageLoop), summaryResponse.content is empty while forwardEmptyMessageResponse is not enabled.
Common situations: Summarization model returning blank output (context overflow, content filter); upstream API degraded; wrong model configured for summarization.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- Empty observation response, leaving queue intact
- ActiveServerQueueManager requires…
- CLAUDE_MEM_QUEUE_ENGINE is not "bullmq"
- SDK turn failed before emitting text, re-queueing the…
- unknown server generation job kind
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/944485c0a62d8a1d.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/worker/OpenAICompatibleProvider.ts:391
}
const summaryResponse = await this.query(session.conversationHistory, summaryConfig);
let tokensUsed = 0;
if (summaryResponse.content) {
// Appended once, by processAgentResponse below — see processObservationMessage.
tokensUsed = summaryResponse.tokensUsed || 0;
session.cumulativeInputTokens += Math.floor(tokensUsed * 0.7);
session.cumulativeOutputTokens += Math.floor(tokensUsed * 0.3);
session.lastUsage = this.buildLastUsage(summaryResponse);
}
if (summaryResponse.content || this.forwardEmptyMessageResponse) {
await processAgentResponse(
summaryResponse.content || '', session, this.dbManager, this.sessionManager,
worker, tokensUsed, originalTimestamp, this.providerName, lastCwd, summaryResponse.servedModel ?? summaryConfig.model, responseContext
);
} else {
logger.warn('SDK', `Empty ${this.providerName} summary response, leaving queue intact`, {
sessionId: session.sessionDbId
});
}
}
/**
* Map a classified provider failure onto the abortReason category that keeps
* buffered work alive.
*
* handleGeneratorExit finalizes the session — dropping whatever is buffered —
* for every category outside its preserve list. Quota was only ever set by
* the two PROACTIVE sites (the pre-request rate-limit guard and the
* observer-text heuristic), so a real 429 coming back from the provider left
* abortReason null and the session was torn down as if the failure were
* fatal (#3700). These conditions clear on their own; the work should still
* be there when they do.
*/
private preservingAbortReason(error: ClassifiedProviderError): string | null {View on GitHub (pinned to d8bc9755e7)