siyuan-note/siyuan · error

AI editor request timeout

Error message

AI editor request timeout

What it means

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.

Solutions

  1. Increase the provider's request timeout in AI provider settings (设置 - AI - provider request timeout)
  2. Verify the provider BaseURL is reachable (curl the /v1/models or chat endpoint)
  3. Check network/proxy configuration and API status of the provider
  4. If using a slow local model (Ollama etc.), raise the timeout substantially

Example fix

// before: provider config with too-short timeout
"requestTimeout": 5
// after
"requestTimeout": 120
Defensive patterns

Strategy: retry

Validate before calling

if (provider.requestTimeout && provider.requestTimeout < 30) {
  console.warn("AI request timeout below 30s may cause frequent timeouts");
}

Try / catch

stream, err := model.NewAIEditorChatStream(ctx, ids, input, action, history)
if err != nil {
    if strings.Contains(err.Error(), "request timeout") {
        // retry once or advise increasing provider timeout
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/66f91e8c81f32330. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/ai.go:194

	messages := buildAIEditorMessages(prompt, history, editing.MaxHistoryMessages)

	req := openai.ChatCompletionRequest{
		Model:               m.Name,
		MaxCompletionTokens: editing.MaxCompletionTokens,
		Temperature:         float32(editing.Temperature),
		Messages:            messages,
		Stream:              true,
	}
	streamCtx, cancel := context.WithCancel(ctx)
	streamCtx = util.ContextWithOpenAIResponsesBaseURL(streamCtx, prov.BaseURL)
	requestTimeout := time.Duration(prov.RequestTimeout) * time.Second
	requestTimer, requestTimerDone := startAIEditorCancelTimer(requestTimeout, cancel)
	client := util.NewOpenAIClientWithModel(prov.APIKey, prov.BaseURL, m.Name, ResolveAIProviderHeaders(prov))
	completionStream, err := util.CreateOpenAICompletionStream(streamCtx, client, prov.Protocol, req, nil)
	requestTimedOut := stopAIEditorCancelTimer(requestTimer, requestTimerDone)
	if requestTimedOut {
		err = errors.New("AI editor request timeout")
	}
	if nil != err {
		cancel()
		return nil, err
	}
	if nil == completionStream {
		cancel()
		return nil, errors.New("AI editor model returned nil stream")
	}
	return &AIEditorChatStream{
		stream:      completionStream,
		cancel:      cancel,
		idleTimeout: 120 * time.Second,
	}, nil
}

func startAIEditorCancelTimer(timeout time.Duration, cancel context.CancelFunc) (*time.Timer, <-chan struct{}) {
	if 0 >= timeout {

View on GitHub (pinned to 9f775e8a12)