siyuan-note/siyuan · error
no AI editing config
Error message
no AI editing config
What it means
NewAIEditorChatStream creates a streaming chat session used by the AI editor. After confirming a provider exists, it reads Conf.AI.Editing, which holds editor-specific AI settings (MaxCompletionTokens, Temperature, MaxHistoryMessages). SiYuan throws "no AI editing config" when that Editing section is nil, meaning the workspace configuration was loaded without (or never received) the AI editing settings block.
Solutions
- Open the workspace conf.json and add a valid "editing" object under "ai" (or restore it from a backup), then restart the kernel
- Set up AI editing via the SiYuan settings UI (设置 - AI) so the editing section is written to conf.json
- Check kernel logs for conf.json unmarshal errors; fix any JSON corruption preventing the editing section from loading
- Verify Conf.AI.Editing is initialized after loading config (upstream default initialization) if running a modified kernel
Example fix
// conf.json (workspace) before
"ai": { "providers": [ ... ] }
// after
"ai": { "providers": [ ... ], "editing": { "maxCompletionTokens": 4096, "temperature": 0.5, "maxHistoryMessages": 10 } } Defensive patterns
Strategy: validation
Validate before calling
if conf.AI == nil || conf.AI.Editing == nil {
return errors.New("AI editing is not configured; open 设置 - AI and save settings")
} Type guard
func hasAIEditingConfig(c *conf.AI) bool { return c != nil && c.Editing != nil } Try / catch
resp, err := api.AIEditorChatStream(req)
if err != nil {
if strings.Contains(err.Error(), "no AI editing config") {
// prompt user to complete AI settings
}
} Prevention
- Never hand-edit conf.json without validating JSON afterwards
- Complete the AI settings UI at least once after creating a workspace
- Back up conf.json before upgrades
When it happens
Trigger: Calling NewAIEditorChatStream (via the aiEditorChatContract API) when conf.AI.Editing is nil — e.g. a hand-edited or partially migrated conf.json that lacks the "editing" object under "ai", or a config struct unmarshalled from an older workspace where the section did not exist.
Common situations: Upgrading an old workspace whose conf.json predates the AI editing feature; manually stripping the ai.editing key; a corrupted or truncated conf.json where the editing object failed to deserialize; tools/scripts that rewrite the config and drop unknown sections.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- AI configuration is unavailable
- Conf.Language(49)
- image model is not configured
- no AI editing model configured
- no AI provider configured
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/73bca98db80107ad.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/ai.go:167
func (stream *AIEditorChatStream) Close() {
stream.cancel()
stream.stream.Close()
}
// NewAIEditorChatStream 创建绑定到编辑器请求生命周期的模型流。
func NewAIEditorChatStream(ctx context.Context, ids []string, input, action string, history []AIEditorMessage) (*AIEditorChatStream, error) {
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,
}View on GitHub (pinned to 9f775e8a12)