plandex-ai/plandex · error

'%s' is not a custom model provider that exists or is being

Error message

'%s' is not a custom model provider that exists or is being imported

What it means

A 422 validation error from UpsertCustomModelsHandler: a custom model in the input declares provider.Provider == shared.ModelProviderCustom with a CustomProvider name that neither already exists in the org's stored providers nor is included in the same request's CustomProviders list. The handler requires custom providers to be imported (in this request) or previously created before a model can reference them.

Source

Thrown at app/server/handlers/models.go:202

	for _, provider := range updatedModelsInput.CustomProviders {
		dbProvider := db.CustomProviderFromApi(provider)
		dbProvider.Id = provider.Id
		dbProvider.OrgId = auth.OrgId

		toUpsertCustomProviders = append(toUpsertCustomProviders, dbProvider)
	}

	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
				}
			}
		}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Add the referenced custom provider definition to the same request's CustomProviders array
  2. Fix the customProvider name to match an existing provider exactly (case-sensitive)
  3. First create the provider via a separate upsert that includes it, then reference it
  4. List current providers (GET custom providers/config) to confirm the exact stored name

Example fix

// before
{"customModels": [{"modelId": "my-model", "providers": [{"provider": "custom", "customProvider": "my-provder"}]}]}
// after
{"customProviders": [{"name": "my-provider", "baseUrl": "https://api.example.com"}], "customModels": [{"modelId": "my-model", "providers": [{"provider": "custom", "customProvider": "my-provider"}]}]}
Defensive patterns

Strategy: validation

Validate before calling

// before calling the API, verify every custom-provider reference is defined or being imported
existing := map[string]bool{"my-provider": true} // fetched from GET custom providers
input := map[string]bool{}
for _, p := range in.CustomProviders { input[p.Name] = true }
for _, m := range in.CustomModels {
    for _, pr := range m.Providers {
        if pr.Provider == "custom" && !existing[*pr.CustomProvider] && !input[*pr.CustomProvider] {
            return fmt.Errorf("provider %q must be created or included in the same request", *pr.CustomProvider)
        }
    }
}

Type guard

func hasResolvableCustomProvider(name string, existing, importing []string) bool {
    for _, e := range existing { if e == name { return true } }
    for _, i := range importing { if i == name { return true } }
    return false
}

Try / catch

// 422 is deterministic — do not retry; fix the payload
if resp.StatusCode == 422 && strings.Contains(bodyText, "not a custom model provider that exists or is being imported") {
    return fmt.Errorf("payload error (no retry): %s", bodyText)
}

Prevention

When it happens

Trigger: POST to the upsert endpoint whose CustomModels[].Providers[] has {"provider":"custom","customProvider":"my-provider"} where 'my-provider' was never created and is not present in the request's CustomProviders array (e.g. typo in the name, or referencing a provider deleted by a previous full-replace upsert).

Common situations: Typo in customProvider name; sending only CustomModels without the matching CustomProviders in the same payload; a prior upsert omitted the provider and the delete-only-what's-missing logic removed it; switching between orgs that have different stored providers.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/20eaecf0698bafa5. Report an issue: GitHub.