siyuan-note/siyuan · error

model stream idle timeout

Error message

model stream idle timeout

What it means

errModelStreamIdleTimeout is a sentinel error returned when an established model stream produces no data within the configured idle timeout. recvStreamWithIdleTimeout starts a timer around stream.Recv(); if the timer fires first, the stream is cancelled and this sentinel is returned, which classifyRetry treats as a retryable "timeout".

Source

Thrown at kernel/agent/agent.go:2445

			e := SessionEntry{
				ID:                   id,
				Type:                 "assistant",
				Content:              m.Content,
				ReasoningCont:        m.ReasoningContent,
				ResponseOutput:       util.CloneOpenAIResponseOutput(m.ResponseOutput),
				ResponseOutputTokens: m.ResponseOutputTokens,
				RoundID:              m.RoundID,
				ToolCalls:            m.ToolCalls,
			}
			entries = append(entries, e)
		}
	}
	return entries
}

var (
	errModelRequestTimeout    = errors.New("model request timeout")
	errModelStreamIdleTimeout = errors.New("model stream idle timeout")
)

func createStreamWithRetry(ctx context.Context, client *openai.Client, req openai.ChatCompletionRequest, maxRetries int,
	requestTimeout, streamIdleTimeout time.Duration, retryDelay func(string, int) time.Duration,
	ch chan<- AgentEvent) (*util.OpenAICompletionStream, openai.ChatCompletionStreamResponse, context.CancelFunc, error) {
	return createProtocolStreamWithRetry(ctx, client, util.OpenAIProtocolChatCompletions, req, nil, maxRetries,
		requestTimeout, streamIdleTimeout, retryDelay, ch)
}

func createProtocolStreamWithRetry(ctx context.Context, client *openai.Client, protocol string,
	req openai.ChatCompletionRequest, responseInput []any, maxRetries int, requestTimeout, streamIdleTimeout time.Duration,
	retryDelay func(string, int) time.Duration,
	ch chan<- AgentEvent) (*util.OpenAICompletionStream, openai.ChatCompletionStreamResponse, context.CancelFunc, error) {
	if maxRetries < 0 {
		maxRetries = 0
	}

	var lastErr error

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Increase the stream idle timeout configuration
  2. Retry — classifyRetry labels this "timeout" and it is retried automatically
  3. Check provider status for stream interruptions
  4. Investigate network paths (proxy/VPN) that may stall long-lived connections
  5. Reduce time-to-first-token by shortening the prompt if stalls occur at stream start
Defensive patterns

Strategy: retry

Try / catch

if errors.Is(err, errModelStreamIdleTimeout) {
    // retryable: back off and reopen the stream, possibly with a larger idle timeout
}

Prevention

When it happens

Trigger: stream.Recv() blocks longer than streamIdleTimeout after a partial (or no) response; stopCancelTimer reports the idle timer expired, so recvStreamWithIdleTimeout returns errModelStreamIdleTimeout instead of the blocked recv.

Common situations: Provider stalls mid-stream (network hiccup, provider-side overload); streamIdleTimeout set too low for slow token generation gaps; long tool-use pauses from the provider with no keep-alive chunks.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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