siyuan-note/siyuan · error

streamed response text does not match the terminal response

Error message

streamed response text does not match the terminal response

What it means

After the terminal response, the adapter compares responseDisplayText(response) with the text accumulated from content deltas. The final text must be identical to, or a strict extension of, what was streamed (an extension is flushed as a final delta). If the final text does not start with the streamed text, the visible conversation would silently change on completion, so the stream fails.

Source

Thrown at kernel/util/openai_completion.go:560

		if current.Function.Arguments != item.Arguments && strings.HasPrefix(item.Arguments, current.Function.Arguments) {
			delta.Function.Arguments = strings.TrimPrefix(item.Arguments, current.Function.Arguments)
			changed = delta.Function.Arguments != "" || changed
		}
		if changed {
			stream.pending = append(stream.pending, openai.ChatCompletionStreamResponse{
				Object: "chat.completion.chunk",
				Choices: []openai.ChatCompletionStreamChoice{{
					Index: 0,
					Delta: openai.ChatCompletionStreamChoiceDelta{ToolCalls: []openai.ToolCall{delta}},
				}},
			})
		}
	}

	fullContent := responseDisplayText(response)
	if currentContent := stream.responseContent.String(); fullContent != currentContent &&
		!strings.HasPrefix(fullContent, currentContent) {
		return errors.New("streamed response text does not match the terminal response")
	}
	if currentContent := stream.responseContent.String(); fullContent != currentContent && strings.HasPrefix(fullContent, currentContent) {
		missing := strings.TrimPrefix(fullContent, currentContent)
		if missing != "" {
			stream.pending = append(stream.pending, openai.ChatCompletionStreamResponse{
				Object: "chat.completion.chunk",
				Choices: []openai.ChatCompletionStreamChoice{{
					Index: 0,
					Delta: openai.ChatCompletionStreamChoiceDelta{Content: missing},
				}},
			})
		}
	}

	finishReason := responseFinishReason(response)
	if hasResponseFunctionCall(response.Output) && finishReason == openai.FinishReasonStop {
		finishReason = openai.FinishReasonToolCalls
	}

View on GitHub (pinned to afa823b6b4)

Solutions

  1. Retry the request once — finalization rewrites are often transient.
  2. Switch that provider to non-streaming requests so the terminal text is the only text.
  3. Upgrade or replace the provider that rewrites streamed content.
  4. Capture an SSE trace and report the divergence.
Defensive patterns

Strategy: fallback

Try / catch

On this error, discard the streamed text and rerun the request non-streaming so the user sees only the terminal text; do not merge the two versions.

Prevention

When it happens

Trigger: Providers that apply filtering, deduplication, or rewriting only at finalization; gateways assembling the final message from a different path than the deltas; safety systems trimming or editing text post-hoc.

Common situations: Content-moderation rewrites on gateways; providers stitching outputs from multiple regions; custom response-assembly middleware between client and model.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/8a608f6e9dfed54c. Report an issue: GitHub.