{"record":{"id":"455179889bf9410d","repo":"jackwener/OpenCLI","slug":"arxiv-label-must-be-maxvalue","errorCode":null,"errorMessage":"arxiv ${label} must be <= ${maxValue}","messagePattern":"arxiv (.+?) must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/arxiv/utils.js","lineNumber":24,"sourceCode":" */\nimport { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';\nexport const ARXIV_BASE = 'https://export.arxiv.org/api/query';\nconst ARXIV_CATEGORY_PATTERN = /^[a-z]+(?:-[a-z]+)*(?:\\.[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*)?$/;\nexport async function arxivFetch(params) {\n    const resp = await fetch(`${ARXIV_BASE}?${params}`);\n    if (!resp.ok) {\n        throw new CommandExecutionError(`arXiv API HTTP ${resp.status}`, 'Check your search term or paper ID');\n    }\n    return resp.text();\n}\nexport function normalizeArxivLimit(value, defaultValue, maxValue, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const limit = Number(raw);\n    if (!Number.isInteger(limit) || limit <= 0) {\n        throw new ArgumentError(`arxiv ${label} must be a positive integer`);\n    }\n    if (limit > maxValue) {\n        throw new ArgumentError(`arxiv ${label} must be <= ${maxValue}`);\n    }\n    return limit;\n}\nexport function normalizeArxivCategory(value) {\n    const category = String(value || '').trim();\n    if (!ARXIV_CATEGORY_PATTERN.test(category)) {\n        throw new ArgumentError(`Invalid arXiv category \"${value}\". Examples: cs.CL, cs.LG, math.PR, q-bio.NC, physics.comp-ph`);\n    }\n    return category;\n}\n/** Decode the small set of XML entities arXiv emits in text fields. */\nfunction decodeEntities(s) {\n    return s\n        .replace(/&amp;/g, '&')\n        .replace(/&lt;/g, '<')\n        .replace(/&gt;/g, '>')\n        .replace(/&quot;/g, '\"')\n        .replace(/&apos;/g, \"'\")","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/arxiv/utils.js#L6-L42","documentation":"ArgumentError thrown by normalizeArxivLimit when the limit is a valid positive integer but exceeds maxValue, the API's upper bound for that option. The library caps limits to protect against oversized arXiv queries that would be rejected or time out.","triggerScenarios":"Calling a search/list command with a limit above the command's maximum (e.g. --limit 500 when max_results is capped at 100 or 200).","commonSituations":"Users trying to bulk-download results in one call; copying a limit from another tool with a higher cap; scripts paginating by requesting huge limits instead of using arXiv paging.","solutions":["Lower the limit to the command's maximum and paginate if more results are needed.","Check the command help for the max value of the limit option.","For bulk needs, run multiple queries (e.g. by category or date range) each within the cap."],"exampleFix":"// before\nopencli arxiv search 'llm' --limit 1000\n// after\nopencli arxiv search 'llm' --limit 100","handlingStrategy":"validation","validationCode":"const MAX_LIMIT = 100; // per command help\nif (limit > MAX_LIMIT) limit = MAX_LIMIT; // or paginate instead","typeGuard":"function isWithinLimit(n, max) {\n  return Number.isInteger(n) && n > 0 && n <= max;\n}","tryCatchPattern":"try {\n  await run(['arxiv', 'search', term, '--limit', String(limit)]);\n} catch (e) {\n  const m = e.message.match(/must be <= (\\d+)/);\n  if (m) {\n    limit = Number(m[1]); // clamp to the documented maximum\n  } else throw e;\n}","preventionTips":["Read the command's help output for the documented maximum before scripting.","Paginate multiple smaller queries instead of one huge limit.","Clamp user-supplied limits to the max in wrapper scripts."],"tags":["validation","arguments","limits"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}