{"record":{"id":"fda90e24f69091b4","repo":"plandex-ai/plandex","slug":"s-is-not-a-built-in-model-provider","errorCode":null,"errorMessage":"'%s' is not a built-in model provider","messagePattern":"'(.+?)' is not a built-in model provider","errorType":"validation","errorClass":null,"httpStatus":422,"severity":"error","filePath":"app/server/handlers/models.go","lineNumber":210,"sourceCode":"\n\tfor _, model := range updatedModelsInput.CustomModels {\n\t\t// ensure that providers to upsert are either built-in, being imported, or already exist\n\t\tfor _, provider := range model.Providers {\n\t\t\tif provider.Provider == shared.ModelProviderCustom {\n\t\t\t\t_, exists := existingCustomProviderNames[*provider.CustomProvider]\n\t\t\t\t_, creating := inputProviderNames[*provider.CustomProvider]\n\t\t\t\tif !exists && !creating {\n\t\t\t\t\tmsg := fmt.Sprintf(\"'%s' is not a custom model provider that exists or is being imported\", *provider.CustomProvider)\n\t\t\t\t\tlog.Println(msg)\n\t\t\t\t\thttp.Error(w, msg, http.StatusUnprocessableEntity)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpc, builtIn := shared.BuiltInModelProviderConfigs[provider.Provider]\n\t\t\t\tif !builtIn {\n\t\t\t\t\tmsg := fmt.Sprintf(\"'%s' is not a built-in model provider\", provider.Provider)\n\t\t\t\t\tlog.Println(msg)\n\t\t\t\t\thttp.Error(w, msg, http.StatusUnprocessableEntity)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif os.Getenv(\"IS_CLOUD\") != \"\" && pc.LocalOnly {\n\t\t\t\t\tmsg := fmt.Sprintf(\"'%s' is a local-only model provider, so it can't be used on Plandex Cloud\", provider.Provider)\n\t\t\t\t\tlog.Println(msg)\n\t\t\t\t\thttp.Error(w, msg, http.StatusUnprocessableEntity)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdbModel := db.CustomModelFromApi(model)\n\t\tdbModel.Id = model.Id\n\t\tdbModel.OrgId = auth.OrgId\n\n\t\ttoUpsertCustomModels = append(toUpsertCustomModels, dbModel)\n\t}\n","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/models.go#L192-L228","documentation":"A 422 validation error thrown when a custom model references provider.Provider as a non-custom value that is not a key in shared.BuiltInModelProviderConfigs. Only built-in provider names (and 'custom' with a valid custom provider) are accepted. This catches misspelled or entirely unknown provider identifiers.","triggerScenarios":"POST to the upsert custom models endpoint with CustomModels[].Providers[].provider set to a string that isn't a built-in provider key — e.g. 'openai ' (trailing space), 'anthropicai', an old/renamed provider id, or a lowercased/uppercased variant.","commonSituations":"Hand-edited models.json config with a typo; copying a provider name from another tool that uses different ids; client/server version skew where the server is older than the provider name the client sends.","solutions":["Use an exact built-in provider name (e.g. openai, anthropic, azure) — check shared.BuiltInModelProviderConfigs for valid keys","If the provider is truly custom, set provider to \"custom\" and supply a CustomProviders entry in the same request","Trim whitespace and fix case in the provider field","Upgrade server and client to matching versions so provider catalogs align"],"exampleFix":"// before\n{\"provider\": \"anthropicai\"}\n// after\n{\"provider\": \"anthropic\"}","handlingStrategy":"validation","validationCode":"// validate provider names against built-ins before calling the API\nbuiltIn := map[string]bool{\"openai\": true, \"anthropic\": true, \"azure\": true /* ...shared.BuiltInModelProviderConfigs */}\nfor _, m := range in.CustomModels {\n    for _, pr := range m.Providers {\n        if pr.Provider != \"custom\" && !builtIn[pr.Provider] {\n            return fmt.Errorf(\"unknown built-in provider: %q\", pr.Provider)\n        }\n    }\n}","typeGuard":"func isBuiltInProvider(p shared.ModelProvider) bool {\n    _, ok := shared.BuiltInModelProviderConfigs[p]\n    return ok\n}","tryCatchPattern":"// deterministic 422 — fix input, never retry\nif resp.StatusCode == 422 && strings.Contains(bodyText, \"is not a built-in model provider\") {\n    var msg string\n    json.Unmarshal(bodyBytes, &msg)\n    return fmt.Errorf(\"fix provider name: %s\", msg)\n}","preventionTips":["Copy provider names from the shared types package, never by hand","Trim and normalize whitespace in config files","Keep client and server versions in sync so provider catalogs match","Use typed constants (shared.ModelProviderX) instead of raw strings"],"tags":["validation","http-422","provider-config"],"backgroundTag":"unknown-provider-name","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}