siyuan-note/siyuan · error
AI editor input is empty
Error message
AI editor input is empty
What it means
After optionally filling input from the given block IDs, the library builds the editor prompt and validates it. If the resulting prompt is entirely whitespace, there is nothing for the AI editor to act on, so the request is refused before contacting the model.
Source
Thrown at kernel/model/ai.go:174
if !Conf.AI.HasAnyProvider() {
return nil, errors.New("no AI provider configured")
}
prov, m := Conf.AI.GetEditingModel()
if nil == prov || nil == m {
return nil, errors.New("no AI editing model configured")
}
editing := Conf.AI.Editing
if nil == editing {
return nil, errors.New("no AI editing config")
}
if "" == input && 0 < len(ids) {
input = getBlocksContent(ids)
}
prompt := BuildAIEditorPrompt(input, action)
if "" == strings.TrimSpace(prompt) {
return nil, errors.New("AI editor input is empty")
}
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)
completionStream, err := util.CreateOpenAICompletionStream(streamCtx, client, prov.Protocol, req, nil)
requestTimedOut := stopAIEditorCancelTimer(requestTimer, requestTimerDone)View on GitHub (pinned to 8641553a1f)
Solutions
- Pass non-empty input text or valid block IDs whose content exists
- Check that the block IDs passed still exist (getBlocksContent returns content only for live blocks)
- Verify the selected action's prompt template yields non-empty text for the given input
Example fix
// before
stream, err := NewAIEditorChatStream("", action, history, nil)
// after
if strings.TrimSpace(input) == "" {
return errors.New("provide text or valid block IDs")
}
stream, err := NewAIEditorChatStream(input, action, history, ids) Defensive patterns
Strategy: validation
Validate before calling
if (!input.trim() && !(ids && ids.length)) { throw new Error('Provide input text or block IDs') } Try / catch
try { await startAIEditor() } catch (e) { if (e.message === 'AI editor input is empty') showToast('Select a block or enter text first') } Prevention
- Check the selection is non-empty before invoking AI editing
- Validate block IDs still exist before passing them
- Test action prompts with empty input to ensure they produce text
When it happens
Trigger: Calling NewAIEditorChatStream with an empty input string and either no ids, ids resolving to empty content, or an action that produces no prompt text; BuildAIEditorPrompt output trims to "".
Common situations: Invoking AI editing on an empty document/block; passing whitespace-only input; action prompt that interpolates only empty user content; getBlocksContent returning nothing for stale/deleted block IDs.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- provider base URL is required
- custom emoji file must not be empty
- no valid IDs provided
- empty HEIF image
- empty HEIF image
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/c71b96d294bb081e.
Report an issue: GitHub.