{"record":{"id":"5f3d92f4bc66a73d","repo":"siyuan-note/siyuan","slug":"provider-not-found","errorCode":null,"errorMessage":"provider not found","messagePattern":"provider not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/api/ai.go","lineNumber":88,"sourceCode":"\t\t}\n\t\tif err = util.ValidateAIProviderHeaders(provider.Headers); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tai := &conf.AI{Providers: []*conf.Provider{provider}}\n\t\tai.Normalize()\n\t\tif len(ai.Providers) != 1 {\n\t\t\treturn nil, errors.New(\"invalid provider config\")\n\t\t}\n\t\treturn ai.Providers[0], nil\n\t}\n\n\tproviderID := request.Provider\n\tfor _, provider := range model.Conf.AI.Providers {\n\t\tif provider != nil && provider.ID == providerID {\n\t\t\treturn provider, nil\n\t\t}\n\t}\n\treturn nil, errors.New(\"provider not found\")\n}\n\nvar chatGPT = contractHandler(apicontract.AIChatGPT, chatGPTContract)\n\nfunc chatGPTContract(c *gin.Context, req apicontract.AIMessageRequest) apicontract.Response[string] {\n\n\treturn apicontract.Success(model.ChatGPT(req.Msg))\n}\n\nvar chatGPTWithAction = contractHandler(apicontract.AIChatGPTWithAction, chatGPTWithActionContract)\n\nfunc chatGPTWithActionContract(c *gin.Context, req apicontract.AIActionRequest) apicontract.Response[string] {\n\n\treturn apicontract.Success(model.ChatGPTWithAction(req.IDs, req.Action))\n}\n\nvar aiEditorChat = contractHandler(apicontract.AIEditorChat, aiEditorChatContract, aiProviderAdmission)\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/api/ai.go#L70-L106","documentation":"resolveAIProvider scans model.Conf.AI.Providers for a provider whose ID matches request.Provider and returns this error when none matches. It is thrown because AI endpoints (chat, test model, list models) require an existing configured provider entry. An empty or misspelled provider ID never resolves.","triggerScenarios":"Calling the AI chat/test-model/list-models API with req.Provider set to an ID that is absent from the workspace config's AI.Providers list (or nil entries only).","commonSituations":"Client still uses a provider ID that was deleted or renamed in settings; config copied from another workspace without the AI section; typo in the ID; tests passing a draft provider ID that was never persisted.","solutions":["List configured providers (GET /api/ai/getProvider or inspect conf) and pass one existing provider.ID","Re-add the missing provider in 设置 - AI with the expected ID","Fix the client/request to send request.Provider instead of a hardcoded stale ID"],"exampleFix":"// before\nbody := {\"provider\": \"openai-old\"}\n// after\n// fetch providers first, use an existing ID\nbody := {\"provider\": providers[0].id}","handlingStrategy":"validation","validationCode":"const conf = await fetchPost('/api/setting/getConf');\nconst ok = conf.data.conf.ai.providers.some(p => p && p.id === providerId);\nif (!ok) throw new Error(`unknown provider: ${providerId}`);","typeGuard":null,"tryCatchPattern":"try { await aiChat({provider}) } catch (e) { if (e.msg === 'provider not found') await reloadAIConfig(); }","preventionTips":["Always fetch the current provider list before referencing a provider ID","Never hardcode provider IDs in clients","After renaming/deleting a provider in settings, update saved consumers"],"tags":["ai","config","provider"],"backgroundTag":"resource-not-found","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"}