{"record":{"id":"99b7b59ab6c3b285","repo":"jackwener/OpenCLI","slug":"label-must-be-a-positive-integer-99b7b5","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/hackernews/read.js","lineNumber":28,"sourceCode":" *   - each subsequent row is a comment, indented by depth (`L0`, `L1`, …)\n *   - `[+N more replies]` summary rows whenever depth/limit cuts in\n */\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nconst HN_ITEM_BASE = 'https://hacker-news.firebaseio.com/v0/item';\n\nasync function fetchItem(id) {\n    const res = await fetch(`${HN_ITEM_BASE}/${id}.json`);\n    if (!res.ok) {\n        throw new CommandExecutionError(`HN API HTTP ${res.status} for item ${id}`, 'Check the item ID');\n    }\n    return res.json();\n}\n\nfunction requirePositiveInt(value, label) {\n    if (!Number.isInteger(value) || value <= 0) {\n        throw new ArgumentError(`${label} must be a positive integer`);\n    }\n    return value;\n}\n\nfunction requireMinInt(value, min, label) {\n    if (!Number.isInteger(value) || value < min) {\n        throw new ArgumentError(`${label} must be an integer >= ${min}`);\n    }\n    return value;\n}\n\n/** HN stores comment text as a small HTML subset — convert to plain text. */\nfunction htmlToText(html) {\n    if (!html) return '';\n    return String(html)\n        .replace(/<p>/gi, '\\n\\n')\n        .replace(/<\\/p>/gi, '')\n        .replace(/<br\\s*\\/?>/gi, '\\n')","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/hackernews/read.js#L10-L46","documentation":"`hackernews read` validates its numeric CLI options through `requirePositiveInt`, which throws `ArgumentError` when a value is not an integer or is <= 0. This guards `--limit`, `--depth`, and `--replies` before any network call is made, so bad input fails fast with a message naming the exact flag. The library throws it because these options control pagination/recursion counts where zero or negative values are meaningless.","triggerScenarios":"Running `opencli hackernews read <id>` with `--limit 0`, `--limit -5`, `--depth 0`, `--replies 0`, or a non-integer like `--limit 2.5` or `--limit abc`. Passing a numeric string via shell variable interpolation that the CLI parser does not coerce to int also triggers it.","commonSituations":"Scripted invocations where limit/depth come from computed shell variables that end up 0 or empty; users assuming 0 means 'unlimited'; typos like `--limit '' ` from an unset env var; pasting float values copied from configs.","solutions":["Check the failing flag named in the message (e.g. `hackernews read --limit`) and set it to a positive integer (1, 2, 3, ...)","Remove the flag entirely to use the default (`--limit 25`, `--depth 2`, `--replies 5`)","If the value comes from a shell variable or script, verify it is non-empty and numeric before invoking the CLI"],"exampleFix":"// before\nopencli hackernews read 39847301 --limit 0\n// after\nopencli hackernews read 39847301 --limit 25","handlingStrategy":"validation","validationCode":"const LIMIT_RE = /^\\d+$/;\nfunction assertPositiveInt(v) {\n  if (!Number.isInteger(Number(v)) || Number(v) <= 0 || !LIMIT_RE.test(String(v))) {\n    throw new Error(`--limit must be a positive integer, got: ${v}`);\n  }\n}\nassertPositiveInt(process.env.HN_LIMIT ?? 25);","typeGuard":"function isPositiveInt(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v > 0;\n}","tryCatchPattern":"try {\n  await run(['opencli', 'hackernews', read, id, '--limit', String(limit)]);\n} catch (e) {\n  if (String(e.message).includes('must be a positive integer')) {\n    console.error(`Bad --limit value: ${limit}; using default 25`);\n    await run(['opencli', 'hackernews', 'read', id]);\n  } else throw e;\n}","preventionTips":["Always pass integer flags as whole numbers; never compute limits with floating-point math","Fall back to defaults instead of empty strings: `${LIMIT:-25}` in shell scripts","Validate numeric env/CLI inputs with Number.isInteger before invoking the CLI"],"tags":["argument-error","cli","validation","input-validation"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}