{"record":{"id":"27b6f7b64227c3ee","repo":"jackwener/OpenCLI","slug":"must-be-max","errorCode":null,"errorMessage":"must be <= ${max}","messagePattern":"must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/grok/export-all.js","lineNumber":22,"sourceCode":"import {\n  normalizeConversationRows,\n  normalizeManifestRows,\n  requireBooleanEvaluateResult,\n  requireObjectEvaluateResult,\n} from './export-utils.js';\nimport { GROK_DOMAIN, GROK_URL } from './utils.js';\n\nfunction normalizeInteger(value, defaultValue, label, { min = 0, max = Number.MAX_SAFE_INTEGER } = {}) {\n  const raw = value ?? defaultValue;\n  const n = Number(raw);\n  if (!Number.isInteger(n)) {\n    throw new ArgumentError(label, `must be an integer`);\n  }\n  if (n < min) {\n    throw new ArgumentError(label, `must be >= ${min}`);\n  }\n  if (n > max) {\n    throw new ArgumentError(label, `must be <= ${max}`);\n  }\n  return n;\n}\n\nasync function waitRandom(page, minMs, maxMs) {\n  if (maxMs <= 0) return;\n  const span = Math.max(0, maxMs - minMs);\n  const ms = minMs + Math.floor(Math.random() * (span + 1));\n  if (ms > 0) await page.wait(ms / 1000);\n}\n\nfunction readManifest(manifestPath, { offset, limit }) {\n  const path = String(manifestPath || '').trim();\n  if (!path) return null;\n  let parsed;\n  try {\n    parsed = JSON.parse(fs.readFileSync(path, 'utf8'));\n  } catch (error) {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/grok/export-all.js#L4-L40","documentation":"ArgumentError thrown by normalizeInteger when an integer option exceeds its configured maximum (max defaults to Number.MAX_SAFE_INTEGER but per-option caps exist for timeouts, delays, and scroll counts). The library enforces sane upper bounds to avoid runaway scraping.","triggerScenarios":"Passing a value > max to limit/offset/maxScrolls/pageScrolls/pageTimeoutMs/delayMinMs, e.g. pageTimeoutMs=999999999.","commonSituations":"Misreading delay units (ms vs seconds) and passing huge values; config files with absurd timeouts; passing Number.MAX_SAFE_INTEGER as 'no limit'.","solutions":["Use values within the documented range for each option","Convert units correctly (seconds to ms) before passing","Clamp with Math.min(max, value)","Remove the override so the documented default applies"],"exampleFix":"// before\ncli.exportAll({ pageTimeoutMs: 60 * 60 * 1000 }); // way above cap\n// after\ncli.exportAll({ pageTimeoutMs: 30 * 1000 });","handlingStrategy":"validation","validationCode":"function clampMax(n, max) { if (n > max) throw new Error(`value ${n} must be <= ${max}`); return n; }","typeGuard":"const isIntLte = (v, max) => Number.isInteger(v) && v <= max;","tryCatchPattern":"try { await cli.exportAll(opts); } catch (e) { if (e.name === 'ArgumentError' && /<= /.test(e.message)) { console.error(`Above maximum: ${e.message}`); } else throw e; }","preventionTips":["Clamp with Math.min(max, v)","Double-check unit conversions (s vs ms) for timeouts/delays","Don't use Number.MAX_SAFE_INTEGER as an 'unlimited' flag — omit the option instead","Keep override values near documented defaults"],"tags":["argument-validation","bounds-check","cli-input"],"backgroundTag":"invalid-argument-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}