{"record":{"id":"e9aede78309780b7","repo":"farion1231/cc-switch","slug":"pi-form-providerkeyrequired","errorCode":null,"errorMessage":"pi.form.providerKeyRequired","messagePattern":"pi\\.form\\.providerKeyRequired","errorType":"validation","errorClass":"PiFormValidationError","httpStatus":null,"severity":"warning","filePath":"src/components/providers/forms/PiProviderForm.tsx","lineNumber":1085,"sourceCode":"      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(\n          t(\"pi.form.modelRequired\"),\n          \"#pi-add-model\",\n          true,\n        );\n      }\n","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/components/providers/forms/PiProviderForm.tsx#L1067-L1103","documentation":"Thrown by PiProviderForm's submit() in create mode only (!isEdit) when providerKey.trim() is empty (PiProviderForm.tsx:1084-1088). providerKey is the provider's config slug in Pi's settings and is live-normalized by handleProviderKeyChange (PiProviderForm.tsx:1063-1066): lowercased with everything outside [a-z0-9-] stripped. fieldSelector is '#pi-provider-key', so the form focuses that field. In edit mode the check is skipped because the immutable providerId is reused.","triggerScenarios":"Creating a provider and leaving the key field empty, or typing characters that all get stripped by the normalizer (e.g. only uppercase CJK text, emojis, underscores, or dots), leaving the normalized value empty.","commonSituations":"Users typing 'My_Key' expect 'my_key' but get 'mykey'; users typing non-Latin-only content end up with an empty key; paste of a name with only symbols/whitespace.","solutions":["Type a key using lowercase letters, digits, and hyphens (normalization applies live, watch the field reflect it)","Pre-fill the key from the display name (slugified) when the user leaves it blank","Disable Save in create mode when the normalized key is empty"],"exampleFix":"// before\nconst trimmedKey = providerKey.trim();\nif (!isEdit && !trimmedKey) throw new PiFormValidationError(t(\"pi.form.providerKeyRequired\"), \"#pi-provider-key\");\n\n// after (derive a slug when the user left it blank)\nconst slug = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\");\nconst trimmedKey = providerKey.trim() || slug(identity.name);","handlingStrategy":"validation","validationCode":"const normalizedKey = identity.providerKey.toLowerCase().replace(/[^a-z0-9-]/g, \"\");\nif (!isEdit && normalizedKey === \"\") {\n  setFormError(t(\"pi.form.providerKeyRequired\"));\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await submit(identity);\n} catch (error) {\n  if (error instanceof Error && error.name === \"PiFormValidationError\") { /* focus '#pi-provider-key' */ return; }\n  throw error;\n}","preventionTips":["Mirror the live normalization (lowercase, [a-z0-9-] only) in your UI hint so users see the final key","Auto-derive a slug from the display name when the key is left blank","Disable Save in create mode while the normalized key is empty"],"tags":["form-validation","pi","slug","normalization"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}