{"record":{"id":"92277b26c2c25ee4","repo":"jackwener/OpenCLI","slug":"label-must-be-a-positive-integer-92277b","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/grok/image.js","lineNumber":18,"sourceCode":"import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, CommandExecutionError, TimeoutError } from '@jackwener/opencli/errors';\nimport { GROK_URL, isOnGrok, normalizeBooleanFlag } from './utils.js';\n\nconst SESSION_HINT = 'Likely login/auth/challenge/session issue in the existing grok.com browser session.';\n\n/**\n * Validate a positive-integer arg without silently flooring/clamping.\n * Throws ArgumentError on `0`, negatives, non-integers, or non-numeric input.\n */\nfunction normalizePositiveInteger(value, defaultValue, label) {\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  return n;\n}\n\nfunction dedupeBySrc(images) {\n  const seen = new Set();\n  const out = [];\n  for (const img of images) {\n    if (!img.src || seen.has(img.src)) continue;\n    seen.add(img.src);\n    out.push(img);\n  }\n  return out;\n}\n\nfunction imagesSignature(images) {\n  return images.map(i => i.src).sort().join('|');\n}","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/grok/image.js#L1-L36","documentation":"normalizePositiveInteger validates numeric CLI options (like --min-count) before use, coercing via Number() and requiring a positive integer result. It throws ArgumentError when the value is missing-but-no-default, non-numeric, zero, negative, or fractional. This ensures downstream loops that fetch N images never run with nonsensical counts.","triggerScenarios":"Calling minCount with --min-count=0, --min-count=-3, --min-count=2.5, --min-count=abc, or an empty string with no default configured.","commonSituations":"Typo in the CLI flag value, shell passing an empty string for an unset variable, or a user trying to say 'no minimum' with 0 instead of omitting the flag.","solutions":["Pass a positive whole number (>= 1) for the option, or omit it to use the default.","If 'no minimum' is intended, drop the flag rather than passing 0.","Quote values in the shell so empty/whitespace values don't slip through as ''."],"exampleFix":"// before\nnode cli.js image --min-count 0\n// after\nnode cli.js image --min-count 3   # or omit the flag entirely","handlingStrategy":"validation","validationCode":"function isValidPositiveInteger(v) {\n  const n = Number(v);\n  return Number.isInteger(n) && n > 0;\n}\nconst minCount = process.env.MIN_COUNT;\nif (minCount !== undefined && !isValidPositiveInteger(minCount)) {\n  throw new Error(`min-count must be a positive integer, got: ${minCount}`);\n}","typeGuard":"function isPositiveInteger(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v > 0;\n}","tryCatchPattern":"try {\n  await cli.image({ minCount });\n} catch (e) {\n  if (e instanceof ArgumentError && /positive integer/.test(e.message)) {\n    console.error(`Bad --min-count value: ${JSON.stringify(minCount)}`);\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Validate numeric CLI inputs with an integer check before invoking the command.","Treat 0 as 'flag omitted', not 'no minimum'.","Use ${VAR:?msg} shell expansion to catch unset variables feeding numeric flags."],"tags":["validation","argument-error","cli-options"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}