{"record":{"id":"eff133c4956b26d3","repo":"farion1231/cc-switch","slug":"pi-form-positivenumberrequired","errorCode":null,"errorMessage":"pi.form.positiveNumberRequired","messagePattern":"pi\\.form\\.positiveNumberRequired","errorType":"validation","errorClass":"PiFormValidationError","httpStatus":null,"severity":"warning","filePath":"src/components/providers/forms/PiProviderForm.tsx","lineNumber":241,"sourceCode":"  let parsed: URL;\n  try {\n    parsed = new URL(value);\n  } catch {\n    throw new Error(errorMessage);\n  }\n  if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n    throw new Error(errorMessage);\n  }\n}\n\nfunction positiveNumber(\n  value: string,\n  errorMessage: string,\n  fieldSelector: string,\n): number {\n  const parsed = Number(value);\n  if (value.trim() === \"\" || !Number.isFinite(parsed) || parsed <= 0) {\n    throw new PiFormValidationError(errorMessage, fieldSelector, true);\n  }\n  return parsed;\n}\n\nfunction supportsImageInput(value: unknown): boolean {\n  return Array.isArray(value) && value.includes(\"image\");\n}\n\nfunction withImageInput(value: unknown, enabled: boolean): string[] {\n  const additionalInputTypes = Array.isArray(value)\n    ? value.filter(\n        (item): item is string =>\n          typeof item === \"string\" && item !== \"text\" && item !== \"image\",\n      )\n    : [];\n  return [\n    \"text\",\n    ...(enabled ? [\"image\"] : []),","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/components/providers/forms/PiProviderForm.tsx#L223-L259","documentation":"positiveNumber in the Pi form rejects values that are empty, non-finite, or <= 0, throwing PiFormValidationError with the localized 'pi.form.positiveNumberRequired' message, the offending field's selector (e.g. '#pi-model-context-window-<key>' or '#pi-model-max-tokens-<key>'), and revealAdvanced=true so the UI can open the advanced panel. Applied to per-model contextWindow and maxTokens fields.","triggerScenarios":"contextWindow or maxTokens field set to '0', '-1', 'abc', '' , or '1e999' (Number() -> Infinity) - Number(value) yields empty/NaN/Infinity/negative.","commonSituations":"Clearing a numeric field and submitting; pasting values with units ('10s', '8k'); minus-sign typos.","solutions":["Enter a plain positive number without units or letters","Validate on change and strip non-numeric characters from the field","Default the field to a sane positive value so it is never empty"],"exampleFix":"// before\ncontextWindow = \"10k\"; // Number('10k') -> NaN -> error\n\n// after\ncontextWindow = \"10000\";","handlingStrategy":"validation","validationCode":"function isPositiveNumberValue(value: string): boolean {\n  const parsed = Number(value);\n  return value.trim() !== \"\" && Number.isFinite(parsed) && parsed > 0;\n}\n\nif (!isPositiveNumberValue(model.contextWindow)) {\n  setFieldError(\n    `#pi-model-context-window-${model.key}`,\n    \"Enter a positive number (no units)\",\n  );\n}","typeGuard":"function isPositiveNumberString(v: string): v is `${number}` {\n  const n = Number(v);\n  return v.trim() !== \"\" && Number.isFinite(n) && n > 0;\n}","tryCatchPattern":"try {\n  buildPiProviderConfig(form);\n} catch (e) {\n  if (e instanceof PiFormValidationError && e.message.includes(\"positiveNumberRequired\")) {\n    focusField(e.fieldSelector); // e.g. '#pi-model-context-window-<key>'\n    revealAdvancedPanel(e.revealAdvanced);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Enter plain numbers - strip units like 'k' or 's' before submit","Default numeric fields to a sane positive value so they are never empty","Filter non-numeric characters on change for contextWindow/maxTokens inputs"],"tags":["form","validation","number","pi"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}