{"record":{"id":"0c797a5f8fd1e11e","repo":"jackwener/OpenCLI","slug":"flaglabel-must-be-a-positive-integer-0c797a","errorCode":null,"errorMessage":"${flagLabel} must be a positive integer","messagePattern":"(.+?) must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/claude/utils.js","lineNumber":82,"sourceCode":"        throw new CommandExecutionError(message);\n    }\n    return state;\n}\n\nexport function requireNonEmptyPrompt(prompt, commandName) {\n    const text = String(prompt ?? '').trim();\n    if (!text) {\n        throw new ArgumentError(\n            `${commandName} prompt cannot be empty`,\n            `Example: opencli ${commandName} \"hello\"`,\n        );\n    }\n    return text;\n}\n\nexport function requirePositiveInt(value, flagLabel, hint) {\n    if (!Number.isInteger(value) || value < 1) {\n        throw new ArgumentError(`${flagLabel} must be a positive integer`, hint);\n    }\n    return value;\n}\n\nexport function requireConversationId(value) {\n    const id = String(value ?? '').trim();\n    if (!id) {\n        throw new ArgumentError(\n            'claude detail requires a conversation id',\n            'Example: opencli claude detail 123e4567-e89b-12d3-a456-426614174000',\n        );\n    }\n    return id;\n}\n\nexport async function getVisibleMessages(page) {\n    const result = await page.evaluate(`(() => {\n        var nodes = document.querySelectorAll('[data-testid=\"user-message\"], ${MESSAGE_SELECTOR}');","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/claude/utils.js#L64-L100","documentation":"requirePositiveInt validates numeric flag values (e.g. --timeout-seconds, --limit) ensuring they are integers >= 1. opencli throws this ArgumentError with the caller-supplied flag label and hint so the CLI surfaces which flag was wrong and how to use it.","triggerScenarios":"Passing --timeout 0, a negative number, a float like 1.5, or a non-numeric value that was coerced to NaN to flags routed through requirePositiveInt (timeoutSeconds, limit).","commonSituations":"Default value 0 treated as 'no timeout' by the caller, unit confusion (milliseconds vs seconds producing 1500), parsing '30s' strings, JS Number('') === 0 from empty env vars.","solutions":["Pass a whole number >= 1 for the flag, e.g. --timeout 30","Check that env vars/config feeding the flag are valid integers, not empty or '0'","Strip unit suffixes ('30s', '1500ms') before converting to a number"],"exampleFix":"// before\nconst limit = Number(process.env.LIMIT || 0); // 0 -> throws\nrequirePositiveInt(limit, '--limit', 'Example: opencli claude --limit 5');\n// after\nconst limit = Number(process.env.LIMIT || 5);\nrequirePositiveInt(limit, '--limit', 'Example: opencli claude --limit 5');","handlingStrategy":"validation","validationCode":"function parsePositiveInt(v) {\n  const n = Number(v);\n  if (!Number.isInteger(n) || n < 1) {\n    throw new Error(`Expected positive integer, got: ${v}`);\n  }\n  return n;\n}\nconst timeout = parsePositiveInt(process.env.TIMEOUT);","typeGuard":"function isPositiveInt(v) {\n  return Number.isInteger(v) && v >= 1;\n}","tryCatchPattern":"try {\n  await command({ timeout });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.includes('must be a positive integer')) {\n    console.error(`Invalid flag value: ${e.message}`);\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Coerce and validate flag values with Number.isInteger before passing","Never use 0 as a sentinel for these flags","Strip time-unit suffixes before numeric conversion","Document flag units (seconds) at call sites"],"tags":["validation","argument-error","cli"],"backgroundTag":"invalid-flag-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}