plandex-ai/plandex · error

'%s' is a local-only model provider, so it can't be used on

Error message

'%s' is a local-only model provider, so it can't be used on Plandex Cloud

What it means

A 422 validation error thrown when the server runs on Plandex Cloud (IS_CLOUD env var set) and a custom model references a built-in provider whose config has LocalOnly=true. Local-only providers rely on locally hosted infrastructure (e.g. ollama, local transformers) that cannot run in the cloud deployment.

Source

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

				_, 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)
	}

	for _, modelPack := range updatedModelsInput.CustomModelPacks {
		// ensure that all models are either built-in, being imported, or already exist
		allModelIds := modelPack.AllModelIds()

		for _, modelId := range allModelIds {
			_, exists := existingCustomModelIds[modelId]

View on GitHub (pinned to e2d772072e)

Solutions

  1. Remove the local-only provider entries from the request when targeting Plandex Cloud
  2. Use a cloud-compatible provider (openai, anthropic, etc.) instead
  3. Run Plandex self-hosted if you need local-only providers like ollama
  4. Keep separate model configs for cloud and self-hosted environments

Example fix

// before (on Plandex Cloud)
{"provider": "ollama"}
// after (on Plandex Cloud)
{"provider": "openai"} // or deploy self-hosted to keep ollama
Defensive patterns

Strategy: validation

Validate before calling

// pre-check LocalOnly providers when targeting Plandex Cloud
if isCloud {
    for _, m := range in.CustomModels {
        for _, pr := range m.Providers {
            if pc, ok := shared.BuiltInModelProviderConfigs[pr.Provider]; ok && pc.LocalOnly {
                return fmt.Errorf("provider %q is local-only; unusable on cloud", pr.Provider)
            }
        }
    }
}

Type guard

func cloudCompatible(p shared.ModelProvider) bool {
    pc, ok := shared.BuiltInModelProviderConfigs[p]
    return ok && !pc.LocalOnly
}

Try / catch

// deterministic 422 — strip local-only providers and resubmit once
if resp.StatusCode == 422 && strings.Contains(bodyText, "local-only model provider") {
    input = stripLocalOnlyProviders(input)
    return upsert(input)
}

Prevention

When it happens

Trigger: POST to the upsert custom models endpoint against api.plandex.ai (or any deployment with IS_CLOUD set) with CustomModels[].Providers[].provider referencing a LocalOnly built-in provider such as ollama.

Common situations: Reusing a local models.json on Plandex Cloud; migrating a self-hosted config to cloud without stripping local providers; not realizing the org/account is in Integrated Models mode restrictions differ from local-only restrictions.

Related errors


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