{"record":{"id":"94d4d4dfb99185f1","repo":"plandex-ai/plandex","slug":"provider-name-is-required","errorCode":null,"errorMessage":"Provider name is required","messagePattern":"Provider name is required","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"app/server/handlers/models.go","lineNumber":71,"sourceCode":"\n\t\t\tif apiOrg.IntegratedModelsMode {\n\t\t\t\thttp.Error(w, \"Custom models are not supported on Plandex Cloud in Integrated Models mode\", http.StatusBadRequest)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\thasDuplicates, errMsg := modelsInput.CheckNoDuplicates()\n\tif !hasDuplicates {\n\t\thttp.Error(w, \"Has duplicates: \"+errMsg, http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tfor _, provider := range modelsInput.CustomProviders {\n\t\tif provider.Name == \"\" {\n\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}","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/models.go#L53-L89","documentation":"Every custom provider in the ModelsInput must have a non-empty Name, which identifies the provider in model configs. If any entry in CustomProviders has an empty Name, the handler rejects the request with HTTP 400 and this message.","triggerScenarios":"POSTing to the custom models upsert endpoint with a CustomProviders element lacking a name field (omitted or empty string in JSON).","commonSituations":"Hand-editing models.json and deleting the name line; programmatically constructing providers where a template field was never filled; a migration script mapping an unnamed source field to provider name.","solutions":["Set a unique, non-empty name on every object in the customProviders array","Validate all provider names client-side before sending the request","If providers were generated by a script, log the raw JSON and check which entry has name: \"\"","Keep names distinct from each other and from built-in provider names to avoid later conflicts"],"exampleFix":"// before\n{\"customProviders\": [{\"baseUrl\": \"https://proxy.example.com\"}]}\n// after\n{\"customProviders\": [{\"name\": \"my-proxy\", \"baseUrl\": \"https://proxy.example.com\"}]}","handlingStrategy":"validation","validationCode":"for i, p := range input.CustomProviders {\n    if p.Name == \"\" {\n        return fmt.Errorf(\"customProviders[%d].name is required\", i)\n    }\n}","typeGuard":"func providerNamed(p *shared.CustomProvider) bool { return p != nil && p.Name != \"\" }","tryCatchPattern":null,"preventionTips":["Validate all provider names are non-empty before each upsert","Require name in any script or template that generates custom providers","Keep provider names unique and descriptive"],"tags":["http","go","validation","missing-field","bad-request"],"backgroundTag":"missing-required-argument","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}