{"record":{"id":"287da3567619b256","repo":"plandex-ai/plandex","slug":"s-is-a-built-in-base-model-id-so-it-can-t-be-use","errorCode":null,"errorMessage":"%s is a built-in base model id, so it can't be used for a custom model","messagePattern":"(.+?) is a built-in base model id, so it can't be used for a custom model","errorType":"validation","errorClass":null,"httpStatus":422,"severity":"error","filePath":"app/server/handlers/models.go","lineNumber":87,"sourceCode":"\t\t\tmsg := \"Provider name is required\"\n\t\t\tlog.Println(msg)\n\t\t\thttp.Error(w, msg, http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t}\n\n\tfor _, model := range modelsInput.CustomModels {\n\t\tif model.ModelId == \"\" {\n\t\t\tmsg := \"Model id is required\"\n\t\t\tlog.Println(msg)\n\t\t\thttp.Error(w, msg, http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tif shared.BuiltInBaseModelsById[model.ModelId] != nil {\n\t\t\tmsg := fmt.Sprintf(\"%s is a built-in base model id, so it can't be used for a custom model\", model.ModelId)\n\t\t\tlog.Println(msg)\n\t\t\thttp.Error(w, msg, http.StatusUnprocessableEntity)\n\t\t\treturn\n\t\t}\n\t}\n\n\tfor _, modelPack := range modelsInput.CustomModelPacks {\n\t\tif modelPack.Name == \"\" {\n\t\t\tmsg := \"Model pack name is required\"\n\t\t\tlog.Println(msg)\n\t\t\thttp.Error(w, msg, http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tif shared.BuiltInModelPacksByName[modelPack.Name] != nil {\n\t\t\tmsg := fmt.Sprintf(\"%s is a built-in model pack name, so it can't be used for a custom model pack\", modelPack.Name)\n\t\t\tlog.Println(msg)\n\t\t\thttp.Error(w, msg, http.StatusUnprocessableEntity)\n\t\t\treturn\n\t\t}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/models.go#L69-L105","documentation":"Custom model ids must not shadow built-in base model ids. The handler checks each custom model's ModelId against shared.BuiltInBaseModelsById; a collision is rejected with HTTP 422 (Unprocessable Entity) and a message naming the offending id. This protects role resolution, which looks ids up in the built-in table first.","triggerScenarios":"POSTing custom models where a modelId exactly matches a built-in base model id (e.g. \"gpt-4o\", \"claude-3-5-sonnet-latest\"), or renaming a custom model to a built-in id.","commonSituations":"Trying to override a built-in model's settings by reusing its id instead of creating a new id; a typo where a wrapper id was meant (e.g. \"gpt-4o-custom\"); upgrading Plandex and a previously-legal custom id becoming a new built-in id.","solutions":["Rename the custom model to a distinct id that does not collide with built-in base model ids","If you want the built-in model's behavior, reference the built-in id directly in your model pack instead of redefining it","To change defaults, define a custom model with a new id and assign it to the desired roles","After a Plandex upgrade, re-check custom ids against the new BuiltInBaseModelsById list"],"exampleFix":"// before\n{\"customModels\": [{\"modelId\": \"gpt-4o\", \"baseUrl\": \"https://proxy.example.com\"}]}\n// after\n{\"customModels\": [{\"modelId\": \"gpt-4o-proxy\", \"baseUrl\": \"https://proxy.example.com\"}]}","handlingStrategy":"validation","validationCode":"for _, m := range input.CustomModels {\n    if shared.BuiltInBaseModelsById[m.ModelId] != nil {\n        return fmt.Errorf(\"%s is a built-in base model id; choose a different custom id\", m.ModelId)\n    }\n}","typeGuard":"func isBuiltInBaseModelId(id shared.ModelId) bool { return shared.BuiltInBaseModelsById[id] != nil }","tryCatchPattern":null,"preventionTips":["Check custom model ids against shared.BuiltInBaseModelsById before submitting","Use suffixed ids (e.g. '-custom', '-proxy') for wrappers around built-in models","Re-validate ids after every Plandex upgrade since built-ins can change"],"tags":["http","go","validation","naming-conflict","unprocessable-entity"],"backgroundTag":"reserved-identifier-conflict","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"}