{"record":{"id":"5432ca6c028b3812","repo":"siyuan-note/siyuan","slug":"errmodelrequesttimeout","errorCode":"errModelRequestTimeout","errorMessage":"model request timeout","messagePattern":"model request timeout","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/agent/agent.go","lineNumber":2514,"sourceCode":"\t\t\t}\n\t\t\te := SessionEntry{\n\t\t\t\tID:                   id,\n\t\t\t\tType:                 \"assistant\",\n\t\t\t\tContent:              m.Content,\n\t\t\t\tReasoningCont:        m.ReasoningContent,\n\t\t\t\tResponseOutput:       util.CloneOpenAIResponseOutput(m.ResponseOutput),\n\t\t\t\tResponseOutputTokens: m.ResponseOutputTokens,\n\t\t\t\tRoundID:              m.RoundID,\n\t\t\t\tToolCalls:            m.ToolCalls,\n\t\t\t}\n\t\t\tentries = append(entries, e)\n\t\t}\n\t}\n\treturn entries\n}\n\nvar (\n\terrModelRequestTimeout    = errors.New(\"model request timeout\")\n\terrModelStreamIdleTimeout = errors.New(\"model stream idle timeout\")\n)\n\nfunc createStreamWithRetry(ctx context.Context, client *openai.Client, req openai.ChatCompletionRequest, maxRetries int,\n\trequestTimeout, streamIdleTimeout time.Duration, retryDelay func(string, int) time.Duration,\n\tch chan<- AgentEvent) (*util.OpenAICompletionStream, openai.ChatCompletionStreamResponse, context.CancelFunc, error) {\n\treturn createProtocolStreamWithRetry(ctx, client, util.OpenAIProtocolChatCompletions, req, nil, maxRetries,\n\t\trequestTimeout, streamIdleTimeout, retryDelay, ch)\n}\n\nfunc createProtocolStreamWithRetry(ctx context.Context, client *openai.Client, protocol string,\n\treq openai.ChatCompletionRequest, responseInput []any, maxRetries int, requestTimeout, streamIdleTimeout time.Duration,\n\tretryDelay func(string, int) time.Duration,\n\tch chan<- AgentEvent) (*util.OpenAICompletionStream, openai.ChatCompletionStreamResponse, context.CancelFunc, error) {\n\tif maxRetries < 0 {\n\t\tmaxRetries = 0\n\t}\n","sourceCodeStart":2496,"sourceCodeEnd":2532,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/agent/agent.go#L2496-L2532","documentation":"errModelRequestTimeout is the sentinel error set when the model chat-completion request exceeds its configured requestTimeout inside createStreamWithRetry. The stream creation context is cancelled with a timer; if the provider has not returned a stream before the deadline, the agent replaces the outcome with this sentinel so classifyRetry treats it as \"timeout\" and applies the timeout retry/backoff policy.","triggerScenarios":"In agent.go (~line 2514/2558): the OpenAI-compatible request to the model endpoint does not produce a stream within requestTimeout; requestTimedOut fires and err is set to errModelRequestTimeout, also matched later by errors.Is in classifyRetry (agent.go:2627) and in tests like TestCreateStreamRequestTimeoutAndZeroRetries.","commonSituations":"Slow or overloaded model provider; very long prompts (near the context limit) that take longer than the configured request timeout; network latency or VPN/proxy slowness; a requestTimeout setting that is too small for the chosen model (e.g. reasoning models with long time-to-first-token).","solutions":["Increase the model request timeout in the AI provider settings so slow-to-start models get enough time.","Check the provider's status/latency; retry when the endpoint is responsive again (the agent retries automatically per maxRetries/classifyRetry).","Reduce prompt size (shorter conversation, tighter compaction) to cut time-to-first-token.","Verify network path (proxy/firewall) to the endpoint is not adding large latency."],"exampleFix":"// before: requestTimeout too small for a slow reasoning model\nstream, _, cancel, err := createStreamWithRetry(ctx, client, req, 2, 5*time.Second, idleTimeout, retryDelay, ch)\n// after: raise the request timeout\nstream, _, cancel, err := createStreamWithRetry(ctx, client, req, 2, 120*time.Second, idleTimeout, retryDelay, ch)","handlingStrategy":"retry","validationCode":"// before sending, sanity-check the configured timeout\nif requestTimeout < 30*time.Second {\n    requestTimeout = 30 * time.Second // floor for slow-to-start models\n}","typeGuard":null,"tryCatchPattern":"stream, _, cancel, err := createStreamWithRetry(ctx, client, req, maxRetries, requestTimeout, idleTimeout, retryDelay, ch)\nif err != nil {\n    if errors.Is(err, errModelRequestTimeout) {\n        // classifyRetry returns \"timeout\"; rely on backoff retry or surface a timeout hint to the user\n    }\n}","preventionTips":["Set requestTimeout generously for reasoning models with long time-to-first-token.","Keep prompts as small as practical to reduce provider latency.","Monitor provider status pages for slow periods.","Ensure retry policy (maxRetries/retryDelay) is enabled for timeout-class errors."],"tags":["timeout","llm","network","agent"],"backgroundTag":"request-timeout","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}