{"record":{"id":"f7d6f98a0e55a475","repo":"jackwener/OpenCLI","slug":"pubmed-label-must-be-a-positive-integer","errorCode":null,"errorMessage":"pubmed ${label} must be a positive integer","messagePattern":"pubmed (.+?) must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/pubmed/utils.js","lineNumber":30,"sourceCode":"    if (!text) {\n        throw new ArgumentError(`pubmed ${label} cannot be empty`);\n    }\n    return text;\n}\n\nexport function requirePmid(value, label = 'pmid') {\n    const pmid = requireText(value, label);\n    if (!/^\\d+$/.test(pmid)) {\n        throw new ArgumentError(`pubmed ${label} must be a numeric PMID`, 'Example: 37780221');\n    }\n    return pmid;\n}\n\nexport function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const text = String(raw).trim();\n    if (!/^\\d+$/.test(text)) {\n        throw new ArgumentError(`pubmed ${label} must be a positive integer`);\n    }\n    const n = Number(text);\n    if (!Number.isSafeInteger(n) || n < 1) {\n        throw new ArgumentError(`pubmed ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`pubmed ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireYear(value, label) {\n    if (value === undefined || value === null || value === '') {\n        return undefined;\n    }\n    const year = requireBoundedInt(value, 1900, 3000, label);\n    if (year < 1800) {\n        throw new ArgumentError(`pubmed ${label} must be >= 1800`);","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pubmed/utils.js#L12-L48","documentation":"requireBoundedInt's first check: the value must be a string of digits only (/^\\d+$/). Any signed, decimal, scientific-notation, or non-numeric value throws ArgumentError 'pubmed <label> must be a positive integer' (typically for the limit option).","triggerScenarios":"`--limit -1`, `--limit 3.5`, `--limit ten`, `--limit ''`, `--limit 1e3`, or values with separators like '1,000'.","commonSituations":"Numbers copied with thousands separators, units appended ('10 results'), negatives from loop counters, floats from other tools.","solutions":["Pass a plain positive integer literal, e.g. `--limit 10`","Remove signs, commas, units, or decimal points","Stringify computed numbers without formatting in scripts"],"exampleFix":"// before\n--limit 1,000\n// after\n--limit 1000","handlingStrategy":"validation","validationCode":"const raw = String(limit ?? '').trim();\nif (!/^\\d+$/.test(raw)) {\n  throw new Error(`limit must be a positive integer, got '${raw}'`);\n}","typeGuard":"function isPositiveIntString(v) {\n  return /^\\d+$/.test(String(v ?? '').trim());\n}","tryCatchPattern":"try {\n  await cli.parse(['pubmed', 'search', query, '--limit', limitArg]);\n} catch (err) {\n  if (err instanceof ArgumentError && /positive integer/.test(err.message)) {\n    console.error(`Bad --limit '${limitArg}'; use a plain integer like 10`);\n    process.exitCode = 2;\n  } else { throw err; }\n}","preventionTips":["Pass limits as plain integer literals (no commas, units, signs, decimals)","Avoid formatting helpers (toLocaleString) when building CLI args","Clamp computed values before passing them as options"],"tags":["validation","argument-error","integer-parsing","cli-options"],"backgroundTag":"invalid-argument-type","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}