{"record":{"id":"cbe99f4be13afd07","repo":"Billionmail/BillionMail","slug":"supplier-not-found","errorCode":null,"errorMessage":"Supplier not found","messagePattern":"Supplier not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/askai/chat.go","lineNumber":251,"sourceCode":"// This function should handle the logic for loading the chat information and return the ChatInfo struct and any error encountered\nfunc GetChatInfo(chatId string) (*ChatInfo, error) {\n\tchatInfo, err := GetChat(chatId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tchatInfo.Messages = GetMessages(chatId)\n\treturn chatInfo, nil\n}\n\nfunc Chat(ctx context.Context, chatId string, supplierName string, modelId string, content string, isText bool) error {\n\tcontent = strings.TrimSpace(content)\n\tif content == \"\" {\n\t\treturn errors.New(\"Content cannot be empty\")\n\t}\n\n\tsupplierInfo, err := GetSupplierConfig(supplierName)\n\tif err != nil {\n\t\treturn errors.New(\"Supplier not found\")\n\t}\n\n\tmodelInfo := GetModelInfo(supplierName, modelId)\n\tif modelInfo == nil {\n\t\treturn errors.New(\"Model not found\")\n\t}\n\n\t// Check if the chat is already active\n\tchatInfo, err := GetChat(chatId)\n\tif err != nil {\n\t\treturn errors.New(\"Chat not found\")\n\t}\n\t// set the chat information\n\tchatInfo.SupplierName = supplierName\n\tchatInfo.ModelId = modelId\n\terr = SaveChat(chatId, chatInfo)\n\tif err != nil {\n\t\treturn errors.New(\"Failed to save chat\")","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/chat.go#L233-L269","documentation":"Chat looks up the named AI supplier configuration via GetSupplierConfig and returns this error when the lookup fails. It means no supplier with that name is registered/configured, so no API key or base URL is available to build the client.","triggerScenarios":"Calling Chat with supplierName that is not among configured suppliers (typo, supplier not added in settings, config not loaded, case mismatch).","commonSituations":"Renaming or deleting a supplier in admin settings while saved chats still reference the old name; spelling mismatch like \"openai\" vs \"OpenAI\"; fresh deployment where supplier credentials were never configured.","solutions":["List configured suppliers and confirm the exact supplierName spelling","Add/configure the supplier (API key, base URL) in the askai settings","Update saved chats/records that reference a renamed or removed supplier"],"exampleFix":"// before\nerr := askai.Chat(ctx, chatId, \"openAi\", modelId, content, true)\n// after\nsuppliers, _ := askai.GetSupplierList() // verify exact name first\nerr := askai.Chat(ctx, chatId, \"openai\", modelId, content, true)","handlingStrategy":"validation","validationCode":"if _, err := askai.GetSupplierConfig(supplierName); err != nil {\n    return fmt.Errorf(\"supplier %q is not configured\", supplierName)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store supplier names from a fetched list rather than hardcoding strings","Seed supplier config in deployment automation","Validate supplier name against config on chat creation, not just at send time"],"tags":["configuration","askai","supplier","missing-config"],"backgroundTag":"supplier-not-configured","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}