siyuan-note/siyuan · error

streamed function call ID does not match the terminal respon

Error message

streamed function call ID does not match the terminal response

What it means

For every terminal function_call item, the adapter cross-checks the call ID accumulated from deltas (current.ID) against item.CallID whenever both are non-empty. A mismatch means the stream and the final response describe different calls — typically a provider regeneration or index swap — and executing either blindly could invoke the wrong function, so the adapter refuses.

Source

Thrown at kernel/util/openai_completion.go:521

	for index := range stream.responseToolCalls {
		if _, ok := terminalToolCalls[index]; !ok {
			return errors.New("streamed function call is missing from the terminal response")
		}
	}
	output, err := MarshalOpenAIResponseOutput(response.Output)
	if err != nil {
		return err
	}
	stream.responseOutput = output

	for index, raw := range response.Output {
		item, ok := responseOutputItem(raw)
		if !ok || item.Type != "function_call" {
			continue
		}
		current := stream.responseToolCalls[index]
		if current.ID != "" && item.CallID != "" && current.ID != item.CallID {
			return errors.New("streamed function call ID does not match the terminal response")
		}
		if current.Function.Name != "" && item.Name != "" && current.Function.Name != item.Name {
			return errors.New("streamed function name does not match the terminal response")
		}
		if current.Function.Arguments != item.Arguments &&
			!strings.HasPrefix(item.Arguments, current.Function.Arguments) {
			return errors.New("streamed function arguments do not match the terminal response")
		}
		delta := openai.ToolCall{Type: openai.ToolTypeFunction}
		deltaIndex := index
		delta.Index = &deltaIndex
		changed := false
		if current.ID == "" && item.CallID != "" {
			delta.ID = item.CallID
			changed = true
		}
		if current.Function.Name == "" && item.Name != "" {
			delta.Function.Name = item.Name

View on GitHub (pinned to afa823b6b4)

Solutions

  1. Retry the request once — transient assembly inconsistencies often clear.
  2. Reproduce against the official OpenAI endpoint to confirm provider fault; upgrade or switch the gateway.
  3. Disable streaming for tool calls on the affected provider.
  4. Report with a captured SSE trace showing both the streamed ID and the terminal item.
Defensive patterns

Strategy: retry

Try / catch

Discard accumulated tool calls and re-issue the request with backoff; if the same index keeps mismatching, permanently switch that provider to non-streaming tool calls.

Prevention

When it happens

Trigger: Gateways regenerating call IDs between streaming and final assembly; parallel tool calls with indices swapped server-side; event translation layers rewriting item identifiers mid-stream.

Common situations: Third-party gateways stitching Responses events from multiple upstream attempts; failover mid-stream; non-compliant Responses-API reimplementations.

Related errors


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