{"record":{"id":"87062858b06f745a","repo":"itwanger/toBeBetterJavaer","slug":"optionname-must-be-a-positive-integer","errorCode":null,"errorMessage":"${optionName} must be a positive integer","messagePattern":"(.+?) must be a positive integer","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/convert-mdnice-images-to-cdn.js","lineNumber":124,"sourceCode":"function requireValue(argv, index) {\n  const value = argv[index + 1];\n  if (!value || value.startsWith(\"-\")) {\n    throw new Error(`Missing value for ${argv[index]}`);\n  }\n  return value;\n}\n\nfunction parseList(value) {\n  return value\n    .split(\",\")\n    .map((item) => item.trim())\n    .filter(Boolean);\n}\n\nfunction parsePositiveInt(value, optionName) {\n  const parsed = Number.parseInt(value, 10);\n  if (!Number.isFinite(parsed) || parsed <= 0) {\n    throw new Error(`${optionName} must be a positive integer`);\n  }\n  return parsed;\n}\n\nfunction loadEnv(envFile) {\n  if (!fs.existsSync(envFile)) {\n    return {};\n  }\n\n  const env = {};\n  const content = fs.readFileSync(envFile, \"utf8\");\n  for (const line of content.split(/\\r?\\n/)) {\n    const trimmed = line.trim();\n    if (!trimmed || trimmed.startsWith(\"#\")) {\n      continue;\n    }\n    const equalsIndex = trimmed.indexOf(\"=\");\n    if (equalsIndex === -1) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/itwanger/toBeBetterJavaer/blob/6617f5fd0b0597735bdc028f2fcd036817877327/scripts/convert-mdnice-images-to-cdn.js#L106-L142","documentation":"Thrown by parsePositiveInt() in scripts/convert-mdnice-images-to-cdn.js when the value passed to --concurrency or --limit is not a base-10 integer greater than zero. Number.parseInt is applied, then the result is rejected if it is non-finite or <= 0. This guards worker-pool sizing and batch limits against zero, negative, fractional, or non-numeric input.","triggerScenarios":"`--concurrency 0`, `--limit -5`, `--concurrency 2.5` (parseInt yields 2, so this one actually passes), `--concurrency abc` (NaN), or `--limit=` (empty string -> NaN). Strictly: any value where parseInt is NaN or the parsed value is <= 0.","commonSituations":"Copy-pasting `--concurrency 0` hoping to disable the limit; passing an empty value via `--limit=`; passing 1e3-style or comma-formatted numbers; a shell variable that expands to nothing.","solutions":["Pass a positive integer: `--concurrency 4` or `--limit 100`","For 'no limit', omit --limit entirely (default is null = unlimited)","Check the shell variable actually expands: `--limit=\"${N}\"` with N unset becomes an empty value — default it first: `--limit=\"${N:-100}\"`"],"exampleFix":"// before\nnode scripts/convert-mdnice-images-to-cdn.js --limit=0\n\n// after (omit --limit for unlimited, or pass a positive count)\nnode scripts/convert-mdnice-images-to-cdn.js --limit=100","handlingStrategy":"validation","validationCode":"function isPositiveInt(v) { return /^\\d+$/.test(String(v)) && Number.parseInt(v, 10) > 0; }\nif (!isPositiveInt(limit)) throw new Error(\"--limit must be a positive integer\");","typeGuard":"const isPositiveInt = (v) => Number.isInteger(Number(v)) && Number(v) > 0 && /^\\d+$/.test(String(v));","tryCatchPattern":"catch (err) { if (err.message.endsWith(\"must be a positive integer\")) { /* re-ask user / clamp to default */ } else throw err; }","preventionTips":["Validate numeric CLI inputs in the calling wrapper before spawning the script","Omit --limit when unlimited is intended instead of passing 0","Quote values from variables and default them"],"tags":["cli","validation","usage-error"],"backgroundTag":null,"analyzedSha":"6617f5fd0b0597735bdc028f2fcd036817877327","analyzedAt":"2026-08-14T14:50:55.107Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}