{"record":{"id":"33c4b921a64bb3e9","repo":"jackwener/OpenCLI","slug":"label-must-be-a-positive-integer-33c4b9","errorCode":null,"errorMessage":"${label} must be a positive integer","messagePattern":"(.+?) must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/_atlassian/shared.js","lineNumber":278,"sourceCode":"export function requirePayloadString(value, field, label) {\n    if (typeof value !== 'string' && typeof value !== 'number') {\n        throw new CommandExecutionError(`${label} did not include a stable ${field}.`);\n    }\n    const s = String(value).trim();\n    if (!s) throw new CommandExecutionError(`${label} did not include a stable ${field}.`);\n    return s;\n}\n\nexport function requireNonEmptyRows(rows, label, hint) {\n    if (!rows.length) throw new EmptyResultError(label, hint);\n    return rows;\n}\n\nexport function parseLimit(value, defaultValue = 20, maxValue = 100, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const n = typeof raw === 'number' ? raw : Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError(`${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireExecute(args, commandName) {\n    if (args.execute !== true) {\n        throw new ArgumentError(`${commandName} requires --execute to perform a remote write`);\n    }\n}\n\nexport async function readUtf8File(filePath) {\n    const path = requireString(filePath, '--file');\n    let fileStat;\n    try {\n        fileStat = await stat(path);","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/_atlassian/shared.js#L260-L296","documentation":"parseLimit throws this ArgumentError when the limit value is not a positive integer (non-numeric string, 0, negative, float, NaN). The CLI validates pagination input locally before hitting the API to avoid pointless requests.","triggerScenarios":"Passing --limit abc, --limit 0, --limit -5, --limit 2.5, or an empty-string limit that coerces to NaN.","commonSituations":"Shell variables containing '20 items' or empty strings; copying a float from config; off-by-one scripts computing 0 results; typos like --limit=1O (letter O).","solutions":["Pass a positive whole number, e.g. --limit 25.","Sanitize/validate shell variables before use: case \"${N}\" in ''|*[!0-9]*) exit 1;; esac or use ${N:?}.","Check for invisible characters/units in the value (tr -d '[:space:]').","In scripts, compute counts with integer arithmetic only."],"exampleFix":"// before\nconst limit = process.env.PAGE_SIZE; // \"50 items\"\nawait run(['--limit', limit]);\n// after\nconst limit = parseInt(process.env.PAGE_SIZE, 10);\nif (!Number.isInteger(limit) || limit <= 0) throw new Error('PAGE_SIZE must be a positive integer');\nawait run(['--limit', String(limit)]);","handlingStrategy":"validation","validationCode":"function parseLimitSafe(v, def = 20) {\n  if (v == null || v === '') return def;\n  const n = Number(v);\n  if (!Number.isInteger(n) || n <= 0) throw new Error(`limit must be a positive integer, got: ${v}`);\n  return n;\n}","typeGuard":"function isPositiveInt(v) { return typeof v === 'number' && Number.isInteger(v) && v > 0; }","tryCatchPattern":"try {\n  await listCmd({ limit: rawLimit });\n} catch (e) {\n  if (e instanceof ArgumentError || /must be a positive integer/.test(e.message)) {\n    console.error(`Bad --limit value \"${rawLimit}\" — use a whole number > 0.`);\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Coerce and validate limit values in one shared helper.","Strip whitespace/units from env-derived numbers.","Use integer-only shell arithmetic when computing page sizes.","Default to a known-good limit (e.g. 25) when input is uncertain."],"tags":["validation","arguments","pagination","cli"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}