siyuan-note/siyuan · error

no AI provider configured

Error message

no AI provider configured

What it means

Returned by chatGPTComplete when Conf.AI.GetEditingModel() returns a nil provider or a nil model. GetEditingModel first requires ai.Editing to be non-nil with a non-empty ModelID, then searches enabled providers for a model whose ID, DisplayName, or Name matches; if none is found (or no provider is enabled), both returns are nil and this error fires. It means the AI editing feature has no usable backend selected.

Source

Thrown at kernel/model/ai.go:91

func chatGPTWithAction(msg string, action string, cloud bool) (ret string) {
	action = strings.TrimSpace(action)
	if "" != action {
		msg = action + ":\n\n" + msg
	}
	ret, _, err := chatGPTComplete(msg, nil, cloud)
	if err != nil {
		return
	}
	return
}

func chatGPTComplete(msg string, contextMsgs []string, cloud bool) (ret string, retContextMsgs []string, err error) {
	util.PushEndlessProgress("Requesting...")
	defer util.ClearPushProgress(100)

	prov, m := Conf.AI.GetEditingModel()
	if nil == prov || nil == m {
		err = errors.New("no AI provider configured")
		return
	}

	editing := Conf.AI.Editing
	if nil == editing {
		err = errors.New("no AI editing config")
		return
	}

	if editing.MaxHistoryMessages < len(contextMsgs) {
		contextMsgs = contextMsgs[len(contextMsgs)-editing.MaxHistoryMessages:]
	}

	var gpt GPT
	if cloud {
		gpt = &CloudGPT{}
	} else {
		gpt = &OpenAIGPT{

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Open Settings - AI and configure at least one provider with a valid API key and base URL, enable it, and select an editing model.
  2. If you edited conf.json by hand, ensure ai.editing.modelId matches an enabled model's id under an enabled provider, and that provider.enabled and model.enabled are true.
  3. Restart the kernel after changing AI config so Conf reloads, or use the settings API to apply the change.
  4. Verify the model Name/ID is spelled exactly (GetEditingModel falls back to DisplayName then Name, but a typo still misses all three).

Example fix

// before: editing.ModelID references a removed model
ai.Editing = &Editing{ModelID: "gpt-3.5-turbo"}  // model no longer present
// after
ai.Editing = &Editing{ModelID: "gpt-4o-mini"}  // matches an enabled model
Defensive patterns

Strategy: validation

Validate before calling

prov, m := Conf.AI.GetEditingModel()
if prov == nil || m == nil {
    return errors.New("configure an AI provider and select an editing model first")
}

Type guard

func editingModelReady(ai *conf.AI) bool {
    p, m := ai.GetEditingModel()
    return p != nil && m != nil
}

Prevention

When it happens

Trigger: Invoking any AI editing entry point (ChatGPT, ChatGPTWithAction, or a cloud AI path) while Conf.AI.GetEditingModel() yields nil — e.g. Editing.ModelID is empty, the referenced model was removed/renamed, or no provider is enabled.

Common situations: Fresh install with no AI provider configured; a user changed a model identifier in config but did not update Editing.ModelID; all providers disabled after an API-key removal; a config migration that reset provider/model enabled flags.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/5051fd5d1568a288. Report an issue: GitHub.