plandex-ai/plandex · error
'%s' is not a built-in model provider
Error message
'%s' is not a built-in model provider
What it means
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.
Source
Thrown at app/server/handlers/models.go:210
for _, model := range updatedModelsInput.CustomModels {
// ensure that providers to upsert are either built-in, being imported, or already exist
for _, provider := range model.Providers {
if provider.Provider == shared.ModelProviderCustom {
_, exists := existingCustomProviderNames[*provider.CustomProvider]
_, creating := inputProviderNames[*provider.CustomProvider]
if !exists && !creating {
msg := fmt.Sprintf("'%s' is not a custom model provider that exists or is being imported", *provider.CustomProvider)
log.Println(msg)
http.Error(w, msg, http.StatusUnprocessableEntity)
return
}
} else {
pc, builtIn := shared.BuiltInModelProviderConfigs[provider.Provider]
if !builtIn {
msg := fmt.Sprintf("'%s' is not a built-in model provider", provider.Provider)
log.Println(msg)
http.Error(w, msg, http.StatusUnprocessableEntity)
return
}
if os.Getenv("IS_CLOUD") != "" && pc.LocalOnly {
msg := fmt.Sprintf("'%s' is a local-only model provider, so it can't be used on Plandex Cloud", provider.Provider)
log.Println(msg)
http.Error(w, msg, http.StatusUnprocessableEntity)
return
}
}
}
dbModel := db.CustomModelFromApi(model)
dbModel.Id = model.Id
dbModel.OrgId = auth.OrgId
toUpsertCustomModels = append(toUpsertCustomModels, dbModel)
}
View on GitHub (pinned to e2d772072e)
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
Example fix
// before
{"provider": "anthropicai"}
// after
{"provider": "anthropic"} Defensive patterns
Strategy: validation
Validate before calling
// validate provider names against built-ins before calling the API
builtIn := map[string]bool{"openai": true, "anthropic": true, "azure": true /* ...shared.BuiltInModelProviderConfigs */}
for _, m := range in.CustomModels {
for _, pr := range m.Providers {
if pr.Provider != "custom" && !builtIn[pr.Provider] {
return fmt.Errorf("unknown built-in provider: %q", pr.Provider)
}
}
} Type guard
func isBuiltInProvider(p shared.ModelProvider) bool {
_, ok := shared.BuiltInModelProviderConfigs[p]
return ok
} Try / catch
// deterministic 422 — fix input, never retry
if resp.StatusCode == 422 && strings.Contains(bodyText, "is not a built-in model provider") {
var msg string
json.Unmarshal(bodyBytes, &msg)
return fmt.Errorf("fix provider name: %s", msg)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- '%s' is not a custom model provider that exists or is being
- '%s' is a local-only model provider, so it can't be used on
- '%s' is not built-in, not being imported, and not an existin
- '%s' is a local-only built-in model, so it can't be used on
- invalid context index: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/fda90e24f69091b4.
Report an issue: GitHub.