{"record":{"id":"e3122fcb1c2719f9","repo":"farion1231/cc-switch","slug":"pi-form-modelrequired","errorCode":null,"errorMessage":"pi.form.modelRequired","messagePattern":"pi\\.form\\.modelRequired","errorType":"validation","errorClass":"PiFormValidationError","httpStatus":null,"severity":"warning","filePath":"src/components/providers/forms/PiProviderForm.tsx","lineNumber":1097,"sourceCode":"        throw new PiFormValidationError(\n          t(\"pi.form.nameRequired\"),\n          'input[name=\"name\"]',\n        );\n      }\n      if (!isEdit && !trimmedKey) {\n        throw new PiFormValidationError(\n          t(\"pi.form.providerKeyRequired\"),\n          \"#pi-provider-key\",\n        );\n      }\n      if (!isEdit && selectedPreset && apiKey.length === 0) {\n        throw new PiFormValidationError(\n          t(\"pi.form.credentialRequired\"),\n          \"#pi-api-key\",\n        );\n      }\n      if (!isEdit && models.length === 0) {\n        throw new PiFormValidationError(\n          t(\"pi.form.modelRequired\"),\n          \"#pi-add-model\",\n          true,\n        );\n      }\n\n      const headers = normalizeRequestHeaders(providerHeaders);\n      const seen = new Set<string>();\n      const normalizedModels = models.map((model, index) => {\n        // Pi treats model IDs as opaque strings. Trimming would rename an\n        // imported model.\n        const id = model.id;\n        if (id.length === 0) {\n          throw new PiFormValidationError(\n            t(\"pi.form.modelIdRequired\", { index: index + 1 }),\n            `#pi-model-id-${model.key}`,\n            true,\n          );","sourceCodeStart":1079,"sourceCodeEnd":1115,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/components/providers/forms/PiProviderForm.tsx#L1079-L1115","documentation":"Thrown by PiProviderForm's submit() in create mode when the models list is empty (PiProviderForm.tsx:1095-1101). A new Pi provider must declare at least one model entry; edit mode is exempt so an existing provider's models can be managed elsewhere. The error targets '#pi-add-model' with revealAdvanced=true, expanding the models section and focusing the add-model control.","triggerScenarios":"Creating a provider, removing every auto-filled model row (or picking a preset/template that ships no models), then saving; programmatic submission before any model rows are added.","commonSituations":"User deletes the prefilled model row intending to add 'the real one' later; custom preset selection leaves models empty; JSON import path that produced zero models.","solutions":["Add at least one model row (ID plus display name) before saving","Re-select the preset so its template models are re-applied","When seeding from an import, default one model entry from the endpoint's known model list"],"exampleFix":"// before\nconst models: PiModelDraft[] = [];\nawait submit(identity);\n\n// after (seed one row when creating)\nconst models = isEdit ? [] : [{ key: crypto.randomUUID(), id: 'my-model', name: 'Default', /* ... */ }];","handlingStrategy":"validation","validationCode":"if (!isEdit && models.length === 0) {\n  setFormError(t(\"pi.form.modelRequired\"));\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await submit(identity);\n} catch (error) {\n  if (error instanceof Error && error.name === \"PiFormValidationError\") { /* expands models section, focuses '#pi-add-model' */ return; }\n  throw error;\n}","preventionTips":["Seed at least one model row from the preset's template values","Disable Save in create mode when the model list is empty","When importing config, verify the import produced >= 1 model before enabling submit"],"tags":["form-validation","pi","models","required-field"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}