{"record":{"id":"6db57b51861f78cf","repo":"jackwener/OpenCLI","slug":"label-must-be-a-positive-integer-6db57b","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/booking/search.js","lineNumber":14,"sourceCode":"import {\n  ArgumentError,\n  CommandExecutionError,\n  EmptyResultError,\n} from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\n\nconst DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction normalizePositiveInt(value, defaultValue, label, max) {\n  const raw = value ?? defaultValue;\n  const n = Number(raw);\n  if (!Number.isInteger(n) || n <= 0) {\n    throw new ArgumentError(`${label} must be a positive integer`);\n  }\n  if (typeof max === 'number' && n > max) {\n    throw new ArgumentError(`${label} must be <= ${max}`);\n  }\n  return n;\n}\n\nfunction normalizeNonNegativeInt(value, defaultValue, label, max) {\n  const raw = value ?? defaultValue;\n  const n = Number(raw);\n  if (!Number.isInteger(n) || n < 0) {\n    throw new ArgumentError(`${label} must be a non-negative integer`);\n  }\n  if (typeof max === 'number' && n > max) {\n    throw new ArgumentError(`${label} must be <= ${max}`);\n  }\n  return n;\n}","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/booking/search.js#L1-L32","documentation":"normalizePositiveInt coerces its input with Number() and requires the result to be an integer strictly greater than 0 (optionally capped by max). This ArgumentError is thrown when the caller passes a value that is missing-and-has-no-default, non-numeric, fractional, negative, or zero for an option labeled by `label` (e.g. adults, rooms, limit). It is an input-validation guard so the booking search CLI never runs with nonsensical counts.","triggerScenarios":"Calling the search command with adults/rooms/limit set to values like 0, -1, 'two', 2.5, '', NaN, or null when no defaultValue applies. Also passing numeric strings with whitespace/units like '2 people', since Number('2 people') is NaN.","commonSituations":"Users typing `--adults 0` or `--limit -5`; config files exporting strings like 'undefined'; programmatically passing a variable that is undefined where the option had no default; parsing user input without trimming; locale-formatted numbers ('2,5').","solutions":["Pass a positive integer (>= 1) for the flagged option, e.g. --adults 2.","If the value comes from user input, parse and validate it first: Number.parseInt + Number.isInteger + n > 0.","Omit the option entirely so the built-in defaultValue applies (value ?? defaultValue), instead of explicitly passing null/0.","Check the error message's `label` to identify exactly which option was invalid and re-run only fixing that one."],"exampleFix":"// before\nawait bookingSearch({ adults: 0, rooms: 1 });\n// throws: adults must be a positive integer\n// after\nawait bookingSearch({ adults: 2, rooms: 1 });","handlingStrategy":"validation","validationCode":"function assertPositiveInt(value, label, max) {\n  const n = Number(value);\n  if (!Number.isInteger(n) || n <= 0) throw new Error(`${label} must be a positive integer`);\n  if (typeof max === 'number' && n > max) throw new Error(`${label} must be <= ${max}`);\n  return n;\n}\nconst adults = assertPositiveInt(opts.adults ?? 2, 'adults', 16);","typeGuard":"function isPositiveInt(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v > 0;\n}","tryCatchPattern":"try {\n  await bookingSearch({ adults, rooms, limit });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.includes('must be a positive integer')) {\n    console.error(`Bad numeric option: ${e.message}`); process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Coerce CLI strings with Number.parseInt(str, 10) and check Number.isInteger before calling.","Never pass sentinel values like 0 or -1; omit the option to use the default.","Share one validation helper across all count options.","Trim/strip units from user input before Number()."],"tags":["argument-validation","cli","input-validation","positive-integer"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}