{"record":{"id":"ebf1e19af3af9357","repo":"jackwener/OpenCLI","slug":"limit-must-be-a-positive-integer-ebf1e1","errorCode":null,"errorMessage":"limit must be a positive integer","messagePattern":"limit must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/gmail/utils.js","lineNumber":31,"sourceCode":"const PAGE_SIZE = 50;\nconst CAPTURE_WAIT_SECONDS = 10;\nconst MAX_BODY_CHARS = 20_000;\n\nexport function unwrapBrowserResult(value, label = 'browser probe') {\n  if (value && typeof value === 'object' && !Array.isArray(value) && 'session' in value) {\n    if (typeof value.session === 'string' && Object.prototype.hasOwnProperty.call(value, 'data')) {\n      return value.data;\n    }\n    throw new CommandExecutionError(`Gmail ${label} returned a malformed Browser Bridge envelope`);\n  }\n  return value;\n}\n\nexport function parseLimit(raw, fallback = DEFAULT_LIMIT, max = MAX_LIMIT) {\n  const value = raw ?? fallback;\n  const limit = Number(value);\n  if (!Number.isInteger(limit) || limit <= 0) {\n    throw new ArgumentError('limit must be a positive integer');\n  }\n  if (limit > max) {\n    throw new ArgumentError(`limit must be <= ${max}`);\n  }\n  return limit;\n}\n\nexport function parseAccount(raw) {\n  const value = raw ?? 0;\n  const account = Number(value);\n  if (!Number.isInteger(account) || account < 0 || account > 20) {\n    throw new ArgumentError('account must be an integer between 0 and 20');\n  }\n  return account;\n}\n\nfunction cleanString(value) {\n  return typeof value === 'string' ? value.trim() : '';","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gmail/utils.js#L13-L49","documentation":"parseLimit validates the user-supplied `limit` argument for gmail list/search commands. The value must coerce via Number() into a positive integer; otherwise ArgumentError is thrown. This is an input-validation guard so bad limits fail fast instead of producing garbage queries.","triggerScenarios":"Passing limit as a non-integer (e.g. 10.5), zero, a negative number, or a non-numeric string like 'all' or '' (empty string coerces to 0). Also passing null when no default applies is treated as fallback, but explicit bad strings fail.","commonSituations":"Typo in a config file (limit: \"twenty\"); shell scripts interpolating empty variables (`--limit $LIMIT` with unset LIMIT); copying an example with a float; user entering 0 expecting 'unlimited'.","solutions":["Pass a positive integer for limit (e.g. 20).","Omit the limit argument entirely to use the default (20).","Fix the calling script/config so it doesn't interpolate empty or non-numeric values.","Clamp/validate user input before forwarding it to the command."],"exampleFix":"// before\ncli --limit all\n// after\ncli --limit 50","handlingStrategy":"validation","validationCode":"const n = Number(limitRaw);\nif (!Number.isInteger(n) || n <= 0) {\n  throw new Error(`limit must be a positive integer, got ${JSON.stringify(limitRaw)}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await gmailSearch({ limit });\n} catch (e) {\n  if (e instanceof ArgumentError && /limit must be a positive integer/.test(e.message)) {\n    return gmailSearch({ limit: 20 }); // fall back to default\n  }\n  throw e;\n}","preventionTips":["Coerce and validate CLI/config values before passing them on.","Use Number.isInteger checks at script boundaries.","Guard against unset shell variables producing empty strings.","Document that limit must be 1..max, never 0 or 'unlimited'."],"tags":["validation","arguments","gmail"],"backgroundTag":"invalid-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}