{"record":{"id":"c03d05a1019d643b","repo":"farion1231/cc-switch","slug":"pi-form-namerequired","errorCode":null,"errorMessage":"pi.form.nameRequired","messagePattern":"pi\\.form\\.nameRequired","errorType":"validation","errorClass":"PiFormValidationError","httpStatus":null,"severity":"warning","filePath":"src/components/providers/forms/PiProviderForm.tsx","lineNumber":1079,"sourceCode":"  }, []);\n\n  const submit = async (identity: ProviderFormData) => {\n    onSubmittingChange?.(true);\n    setFormError(null);\n    try {\n      if (!isEdit && selectedPresetId === null) {\n        throw new PiFormValidationError(t(\"pi.form.selectPresetRequired\"));\n      }\n      if (!parseJsonObject(identity.settingsConfig)) {\n        throw new PiFormValidationError(\n          t(\"jsonEditor.mustBeObject\"),\n          \"#pi-settings-config\",\n        );\n      }\n      const trimmedName = identity.name.trim();\n      const trimmedKey = providerKey.trim();\n      if (!trimmedName) {\n        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(","sourceCodeStart":1061,"sourceCodeEnd":1097,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/components/providers/forms/PiProviderForm.tsx#L1061-L1097","documentation":"Thrown by PiProviderForm's submit() when identity.name.trim() is empty (PiProviderForm.tsx:1075-1082). The provider display name is mandatory in both create and edit mode; whitespace-only names are rejected because the check runs on the trimmed value. fieldSelector is 'input[name=\"name\"]', so the form focuses the name input after surfacing the inline error and toast.","triggerScenarios":"Submitting with an empty Name field, or a name consisting only of spaces/tabs/newlines; programmatic submissions that never set identity.name.","commonSituations":"User tabs past the name field assuming the preset fills it; pasting a name that is only whitespace; edit flows that clear the name but keep other fields.","solutions":["Enter a non-blank display name and save again","Trim client input and disable Save when name.trim() === ''","If names should auto-derive, default them from the selected preset's label before submit"],"exampleFix":"// before\nconst values = { name: identity.name, ... };\n\n// after\nconst values = { name: identity.name.trim(), ... };\n// and disable submit when identity.name.trim() === ''","handlingStrategy":"validation","validationCode":"const trimmedName = identity.name.trim();\nif (trimmedName === \"\") {\n  setFormError(t(\"pi.form.nameRequired\"));\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await submit(identity);\n} catch (error) {\n  if (error instanceof Error && error.name === \"PiFormValidationError\") { /* inline error, focus name input */ return; }\n  throw error;\n}","preventionTips":["Disable Save while the trimmed name is empty","Trim on change, not only on submit, so whitespace-only input is visible","Pre-fill the name from the selected preset label in create mode"],"tags":["form-validation","pi","required-field","whitespace"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}