plandex-ai/plandex · error

'%s' is not built-in, not being imported, and not an existin

Error message

'%s' is not built-in, not being imported, and not an existing custom model

What it means

A 422 validation error from UpsertCustomModelsHandler: a model pack references a model id (from modelPack.AllModelIds()) that is not a built-in base model (shared.BuiltInBaseModelsById), not an existing stored custom model for the org, and not included in the same request's CustomModels. Every model a pack references must be resolvable to one of those three sources.

Source

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

		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]
			_, creating := inputModelIds[string(modelId)]
			bm, builtIn := shared.BuiltInBaseModelsById[modelId]

			if !exists && !creating && !builtIn {
				msg := fmt.Sprintf("'%s' is not built-in, not being imported, and not an existing custom model", modelId)
				log.Println(msg)
				http.Error(w, msg, http.StatusUnprocessableEntity)
				return
			}

			if builtIn && os.Getenv("IS_CLOUD") != "" && bm.IsLocalOnly() {
				msg := fmt.Sprintf("'%s' is a local-only built-in model, so it can't be used on Plandex Cloud", modelId)
				log.Println(msg)
				http.Error(w, msg, http.StatusUnprocessableEntity)
				return
			}
		}

		mp := modelPack.ToModelPack()
		dbMp := db.ModelPackFromApi(&mp)
		dbMp.OrgId = auth.OrgId
		dbMp.Id = mp.Id

		toUpsertModelPacks = append(toUpsertModelPacks, dbMp)
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Include the referenced custom model's definition in the same request's CustomModels array
  2. Fix the model id to exactly match a built-in base model id
  3. Create the custom model first with a prior upsert, then submit the pack
  4. Verify ids against the org's current custom models list before submitting

Example fix

// before
{"customModelPacks": [{"name": "my-pack", "planner": {"modelId": "my-missing-model"}}]}
// after
{"customModels": [{"modelId": "my-missing-model", "providers": [...]}], "customModelPacks": [{"name": "my-pack", "planner": {"modelId": "my-missing-model"}}]}
Defensive patterns

Strategy: validation

Validate before calling

// ensure every model id referenced by packs resolves to built-in, existing, or in-request
existing := fetchExistingCustomModelIds(org)
inRequest := map[string]bool{}
for _, m := range in.CustomModels { inRequest[string(m.ModelId)] = true }
for _, pack := range in.CustomModelPacks {
    for _, id := range pack.AllModelIds() {
        _, builtIn := shared.BuiltInBaseModelsById[id]
        if !builtIn && !existing[id] && !inRequest[string(id)] {
            return fmt.Errorf("pack references unresolvable model id: %q", id)
        }
    }
}

Type guard

func modelIdResolvable(id shared.ModelId, existing map[shared.ModelId]bool, inRequest map[string]bool) bool {
    if _, ok := shared.BuiltInBaseModelsById[id]; ok { return true }
    return existing[id] || inRequest[string(id)]
}

Try / catch

// deterministic 422 — no retry; include missing models and resubmit
if resp.StatusCode == 422 && strings.Contains(bodyText, "not built-in, not being imported, and not an existing custom model") {
    return fmt.Errorf("add missing model definitions to CustomModels: %s", bodyText)
}

Prevention

When it happens

Trigger: POST to the upsert endpoint with a CustomModelPacks entry whose roles (planner, coder, summarizer, etc.) reference a model id that was never defined — e.g. referencing 'gpt-4-turbo-custom' when no such custom model exists and the pack omits its definition, or a model that was dropped from CustomModels in this same full-replace request.

Common situations: Hand-editing a model pack and referencing a model defined in a different file; partial imports that send packs but not their models; a previous full-replace upsert deleted the custom model the pack depends on; typo in a base model id that is close to but not exactly a built-in id.

Related errors


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