can1357/oh-my-pi · error
V2 compaction stream closed before response.completed
Error message
V2 compaction stream closed before response.completed
What it means
The SSE stream from the V2 compaction endpoint terminated without ever delivering a response.completed event (state.sawCompleted false), so the collected data cannot be trusted as a finished compaction. This guards against accepting partial results from a truncated or dropped connection.
Source
Thrown at packages/agent/src/compaction/compaction-v2-streaming.ts:529
dataLines.push(buffer.slice("data:".length).trimStart());
} else if (buffer.startsWith("event:")) {
eventName = buffer.slice("event:".length).trim();
}
}
dispatch();
} finally {
reader.releaseLock();
}
return finishCompactionV2Collection(state, request);
}
function finishCompactionV2Collection(
state: CompactionV2CollectionState,
request: CompactionV2Request,
): CompactionV2Response {
if (!state.sawCompleted) {
throw new Error("V2 compaction stream closed before response.completed");
}
if (state.compactionItems.length !== 1) {
throw new Error(
`V2 compaction expected exactly one compaction output item, got ${state.compactionItems.length} from ${state.outputItemCount} output items`,
);
}
const compactionItem = state.compactionItems[0];
const { replacementHistory, retainedImageCount } = buildCompactionV2ReplacementHistory(
request.input,
compactionItem,
request.retainedMessageBudget,
);
return {
compactionItem,
replacementHistory,
usedTokens: state.usage?.inputTokens ?? 0,
usage: state.usage,View on GitHub (pinned to 9690622007)
Solutions
- Retry the compaction — requestCompactionV2Streaming's retry logic (retryWait option) is designed for transient stream drops
- Increase proxy/gateway idle timeouts for the compaction endpoint to exceed expected compaction duration
- Disable response buffering on intermediaries (e.g. proxy_buffering off for nginx) so SSE events flow
- Check server logs/status for early connection termination; if persistent, fall back to local compaction
Example fix
// before
await requestCompactionV2Streaming({ model, ... }); // stream drops behind 60s proxy timeout
// after
await requestCompactionV2Streaming({ model, retryWait: (ms) => Bun.sleep(ms), ... });
// plus: nginx: proxy_read_timeout 600s; proxy_buffering off; Defensive patterns
Strategy: retry
Validate before calling
// keep intermediary timeouts longer than worst-case compaction // e.g. nginx: proxy_read_timeout 600s; proxy_buffering off;
Try / catch
try {
return await requestCompactionV2Streaming({ model, ... });
} catch (err) {
if (err instanceof Error && err.message.includes("closed before response.completed")) {
await Bun.sleep(backoff);
return requestCompactionV2Streaming({ model, ... }); // transient drop: retry
}
throw err;
} Prevention
- Configure proxies/LBs with idle timeouts exceeding compaction duration and SSE buffering disabled
- Use requestCompactionV2Streaming's retryWait for automatic retries on stream drops
- Fall back to local compaction after repeated truncations
When it happens
Trigger: Connection drops mid-stream, server closes the SSE connection after an error without response.failed, a proxy/load-balancer times out the long-running stream, or [DONE] arrives before any response.completed event.
Common situations: Long compaction requests crossing proxy idle timeouts (e.g. 60s gateways); network interruptions on mobile/VPN; Azure OpenAI closing streams under load; misconfigured reverse proxy buffering/killing SSE.
Related errors
- V2 compaction stream parse failed: ${err instanceof Error ?
- stream ended before message_start
- Google API stream ended without a finish reason (connection
- SSE stream ended without a resumable event ID
- Perplexity ask stream error: ${message}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ae59e62b678aebeb.
Report an issue: GitHub.