{"record":{"id":"66f91e8c81f32330","repo":"siyuan-note/siyuan","slug":"ai-editor-request-timeout","errorCode":null,"errorMessage":"AI editor request timeout","messagePattern":"AI editor request timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/ai.go","lineNumber":194,"sourceCode":"\n\tmessages := buildAIEditorMessages(prompt, history, editing.MaxHistoryMessages)\n\n\treq := openai.ChatCompletionRequest{\n\t\tModel:               m.Name,\n\t\tMaxCompletionTokens: editing.MaxCompletionTokens,\n\t\tTemperature:         float32(editing.Temperature),\n\t\tMessages:            messages,\n\t\tStream:              true,\n\t}\n\tstreamCtx, cancel := context.WithCancel(ctx)\n\tstreamCtx = util.ContextWithOpenAIResponsesBaseURL(streamCtx, prov.BaseURL)\n\trequestTimeout := time.Duration(prov.RequestTimeout) * time.Second\n\trequestTimer, requestTimerDone := startAIEditorCancelTimer(requestTimeout, cancel)\n\tclient := util.NewOpenAIClientWithModel(prov.APIKey, prov.BaseURL, m.Name, ResolveAIProviderHeaders(prov))\n\tcompletionStream, err := util.CreateOpenAICompletionStream(streamCtx, client, prov.Protocol, req, nil)\n\trequestTimedOut := stopAIEditorCancelTimer(requestTimer, requestTimerDone)\n\tif requestTimedOut {\n\t\terr = errors.New(\"AI editor request timeout\")\n\t}\n\tif nil != err {\n\t\tcancel()\n\t\treturn nil, err\n\t}\n\tif nil == completionStream {\n\t\tcancel()\n\t\treturn nil, errors.New(\"AI editor model returned nil stream\")\n\t}\n\treturn &AIEditorChatStream{\n\t\tstream:      completionStream,\n\t\tcancel:      cancel,\n\t\tidleTimeout: 120 * time.Second,\n\t}, nil\n}\n\nfunc startAIEditorCancelTimer(timeout time.Duration, cancel context.CancelFunc) (*time.Timer, <-chan struct{}) {\n\tif 0 >= timeout {","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/ai.go#L176-L212","documentation":"NewAIEditorChatStream starts a cancel timer for prov.RequestTimeout seconds around the call to util.CreateOpenAICompletionStream. If the timer fires first, the context is cancelled and the stream creation is abandoned; SiYuan replaces the underlying error with \"AI editor request timeout\". This means the provider endpoint did not begin streaming a completion within the configured timeout.","triggerScenarios":"The AI provider (OpenAI-compatible endpoint at prov.BaseURL) is slow, unreachable, or rate-limited so that CreateOpenAICompletionStream does not return a stream within prov.RequestTimeout seconds; prov.RequestTimeout set to a very small value.","commonSituations":"Slow or overloaded third-party API provider; network egress blocked by firewall/proxy; misconfigured BaseURL pointing to a dead host; RequestTimeout left at a low default when using a slow local model.","solutions":["Increase the provider's request timeout in AI provider settings (设置 - AI - provider request timeout)","Verify the provider BaseURL is reachable (curl the /v1/models or chat endpoint)","Check network/proxy configuration and API status of the provider","If using a slow local model (Ollama etc.), raise the timeout substantially"],"exampleFix":"// before: provider config with too-short timeout\n\"requestTimeout\": 5\n// after\n\"requestTimeout\": 120","handlingStrategy":"retry","validationCode":"if (provider.requestTimeout && provider.requestTimeout < 30) {\n  console.warn(\"AI request timeout below 30s may cause frequent timeouts\");\n}","typeGuard":null,"tryCatchPattern":"stream, err := model.NewAIEditorChatStream(ctx, ids, input, action, history)\nif err != nil {\n    if strings.Contains(err.Error(), \"request timeout\") {\n        // retry once or advise increasing provider timeout\n    }\n}","preventionTips":["Set provider request timeout >= 60s for slow providers or local models","Monitor provider status/uptime","Verify BaseURL reachability after network or proxy changes"],"tags":["ai","network","timeout"],"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"}