{"record":{"id":"5cfaf8580ec8ce46","repo":"farion1231/cc-switch","slug":"provider-key-is-required","errorCode":null,"errorMessage":"Provider key is required","messagePattern":"Provider key is required","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/0b5da510168914b251481654a568c3ffacd62cf4/src/components/providers/forms/PiProviderForm.tsx#L1067-L1103","documentation":"In create mode, PiProviderForm requires a provider key: submit() trims providerKey and throws pi.form.providerKeyRequired (focusing #pi-provider-key) when it is empty. Note handleProviderKeyChange normalizes every keystroke with value.toLowerCase().replace(/[^a-z0-9-]/g, \"\"), so a key made entirely of disallowed characters (spaces, underscores, CJK, emoji) is coerced to the empty string and trips this error even though the user typed something.","triggerScenarios":"Submitting the create form with the provider key blank; typing a key like \"my key\" is fine (becomes \"mykey\"), but typing \"我的\" or \"###\" normalizes to \"\" and throws. Editing an existing provider never throws this (guarded by !isEdit).","commonSituations":"Users paste a provider title with only non-ASCII characters; an IME composition inserts characters that are all stripped; the key input was cleared by the normalizer after paste.","solutions":["Enter a provider key using only lowercase letters, digits, and hyphens (e.g. \"my-pi-provider\").","If your typed input keeps disappearing, check for characters outside [a-z0-9-] — switch the IME to half-width ASCII input.","Convert offending separators yourself before typing: replace spaces with hyphens rather than relying on deletion."],"exampleFix":"// before\nhandleProviderKeyChange(\"My Provider_\"); // stored as \"myprovider\" ok\nhandleProviderKeyChange(\"配置\"); // normalizes to \"\" -> throws on submit\n\n// after\nhandleProviderKeyChange(\"custom-provider-1\"); // passes [a-z0-9-] filter unchanged","handlingStrategy":"validation","validationCode":"const normalizeKey = (v: string) => v.toLowerCase().replace(/[^a-z0-9-]/g, \"\");\nconst keyOk = isEdit || normalizeKey(providerKey).length > 0;\nif (!keyOk) warnUser(\"Provider key needs a-z, 0-9 or - characters\");","typeGuard":null,"tryCatchPattern":"catch (e) {\n  if (e instanceof PiFormValidationError && e.fieldSelector === \"#pi-provider-key\") { showHint(\"Use lowercase letters, digits, hyphens\"); return; }\n  throw e;\n}","preventionTips":["Show a live preview of the normalized key under the input so users see it collapse to empty.","Substitute allowed characters (space -> '-') during normalization instead of only stripping."],"tags":["pi","form-validation","slug-normalization","react"],"backgroundTag":"required-form-field-missing","analyzedSha":"0b5da510168914b251481654a568c3ffacd62cf4","analyzedAt":"2026-08-20T14:29:00.113Z","contentChangedAt":"2026-08-20T14:29:00.113Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}