{"record":{"id":"a20a703fb64861b8","repo":"farion1231/cc-switch","slug":"pi-form-modelnamerequired","errorCode":null,"errorMessage":"pi.form.modelNameRequired","messagePattern":"pi\\.form\\.modelNameRequired","errorType":"validation","errorClass":"PiFormValidationError","httpStatus":null,"severity":"warning","filePath":"src/components/providers/forms/PiProviderForm.tsx","lineNumber":1132,"sourceCode":"            true,\n          );\n        }\n        if (seen.has(id)) {\n          throw new PiFormValidationError(\n            t(\"pi.form.duplicateModel\", { id }),\n            `#pi-model-id-${model.key}`,\n            true,\n          );\n        }\n        seen.add(id);\n        const displayName = model.name.trim();\n        const includeName = !isEdit || model.hasName;\n        const includeReasoning = !isEdit || model.hasReasoning;\n        const includeInput = !isEdit || model.hasInput;\n        const includeContextWindow = !isEdit || model.hasContextWindow;\n        const includeMaxTokens = !isEdit || model.hasMaxTokens;\n        if (includeName && !displayName) {\n          throw new PiFormValidationError(\n            t(\"pi.form.modelNameRequired\", { index: index + 1 }),\n            `#pi-model-name-${model.key}`,\n            true,\n          );\n        }\n        const contextWindow = includeContextWindow\n          ? positiveNumber(\n              model.contextWindow,\n              t(\"pi.form.positiveNumberRequired\", {\n                label: t(\"pi.form.contextWindow\"),\n              }),\n              `#pi-model-context-window-${model.key}`,\n            )\n          : undefined;\n        const maxTokens = includeMaxTokens\n          ? positiveNumber(\n              model.maxTokens,\n              t(\"pi.form.positiveNumberRequired\", {","sourceCodeStart":1114,"sourceCodeEnd":1150,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/components/providers/forms/PiProviderForm.tsx#L1114-L1150","documentation":"Thrown per-model in PiProviderForm's submit() when a model's display name is required but empty after trimming (PiProviderForm.tsx:1128-1135). includeName is always true in create mode, but in edit mode it is only true when the row's name field exists (model.hasName), preserving imported models that legitimately have no name. The message interpolates the 1-based row index; fieldSelector '#pi-model-name-{model.key}' with revealAdvanced=true expands and focuses that row's name input.","triggerScenarios":"Creating a provider with a model row whose Name is blank; editing a row where the name toggle/field was enabled but left empty; whitespace-only names.","commonSituations":"Users assume the display name is optional because the ID is the machine key; preset templates that ship nameless models get edited; clearing a name while editing instead of removing the field.","solutions":["Enter a display name on the row indicated by the index in the message","In edit mode, remove the name from the row's config (so hasName is false) rather than leaving it empty","Auto-fill name from the model id when the user leaves it blank"],"exampleFix":"// before\nconst displayName = model.name.trim();\nif (includeName && !displayName) throw /* pi.form.modelNameRequired */;\n\n// after (fall back to the id instead of erroring, if your UX allows)\nconst displayName = model.name.trim() || model.id;","handlingStrategy":"validation","validationCode":"for (const [i, m] of models.entries()) {\n  const includeName = !isEdit || m.hasName;\n  if (includeName && m.name.trim() === \"\") {\n    setFormError(t(\"pi.form.modelNameRequired\", { index: i + 1 }));\n    return;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await submit(identity);\n} catch (error) {\n  if (error instanceof Error && error.name === \"PiFormValidationError\") { /* '#pi-model-name-{key}' is focused and the row auto-expands */ return; }\n  throw error;\n}","preventionTips":["Auto-suggest the display name from the model id when left blank","In edit mode, offer 'remove name' (clear hasName) instead of an empty string","Trim on blur so whitespace-only names are caught visually"],"tags":["form-validation","pi","models","display-name"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}