siyuan-note/siyuan · error

compaction summary stream failed: %w

Error message

compaction summary stream failed: %w

What it means

Wraps a mid-stream failure of the compaction summary request. The request started successfully, but receiving a stream chunk returned a non-EOF error (network drop, provider stream error event, idle-timeout on the stream), so partial token counts and the incomplete summary are discarded and the error is wrapped for reporting.

Source

Thrown at kernel/agent/compaction.go:228

	defer stream.Close()
	defer cancel()

	var summaryBuilder strings.Builder
	firstResponsePending := true
	for {
		response := firstResponse
		var receiveErr error
		if firstResponsePending {
			firstResponsePending = false
		} else {
			response, receiveErr = recvStreamWithIdleTimeout(stream, streamIdleTimeout, cancel)
		}
		if receiveErr != nil {
			if errors.Is(receiveErr, io.EOF) {
				break
			}
			return "", promptTokens, completionTokens,
				fmt.Errorf("compaction summary stream failed: %w", receiveErr)
		}
		for _, choice := range response.Choices {
			summaryBuilder.WriteString(choice.Delta.Content)
		}
		if response.Usage != nil {
			promptTokens = response.Usage.PromptTokens
			completionTokens = response.Usage.CompletionTokens
		}
	}
	summary = strings.TrimSpace(summaryBuilder.String())
	if summary == "" {
		return "", promptTokens, completionTokens, errCompactionSummaryEmpty
	}
	return summary, promptTokens, completionTokens, nil
}

func createResponseCompaction(ctx context.Context, client *openai.Client, request openai.ChatCompletionRequest,
	responseInput []any, maxRetries int, requestTimeout time.Duration,

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Retry the compaction; the wrapper's cause tells whether it was a timeout, reset, or API error
  2. Increase streamIdleTimeout if the model pauses between chunks
  3. Check network stability (VPN/proxy) or switch to a more reliable provider endpoint
  4. Reduce summary size (lower compactionSummaryMaxTokens) so the stream finishes faster
Defensive patterns

Strategy: retry

Try / catch

if err != nil { if ne, ok := err.(net.Error); ok && ne.Timeout() { /* increase streamIdleTimeout and retry */ }; return fmt.Errorf("compaction aborted: %w", err) }

Prevention

When it happens

Trigger: During createProtocolCompactionSummary's receive loop: stream receive returns an error other than io.EOF — connection reset, stream idle timeout exceeded, provider sending an error event mid-stream, or the stream being closed unexpectedly.

Common situations: Long summary generations interrupted by unstable networks (mobile, VPN, proxies); providers closing idle streams; server-side overload dropping the SSE connection; streamIdleTimeout too aggressive for a slow model.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/cc7d04557b9a7bf5. Report an issue: GitHub.