{"record":{"id":"40f5ceabd37f8168","repo":"jackwener/OpenCLI","slug":"huodongxing-limit-must-be-max-limit","errorCode":null,"errorMessage":"huodongxing limit must be <= ${MAX_LIMIT}","messagePattern":"huodongxing limit must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/huodongxing/events.js","lineNumber":30,"sourceCode":"  'eventType',\n  'city',\n  'location',\n  'organizer',\n  'url',\n];\n\nfunction cleanText(value) {\n  return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nexport function requireLimit(value) {\n  const raw = value ?? 20;\n  const limit = typeof raw === 'number' ? raw : Number(String(raw).trim());\n  if (!Number.isInteger(limit) || limit <= 0) {\n    throw new ArgumentError('huodongxing limit must be a positive integer');\n  }\n  if (limit > MAX_LIMIT) {\n    throw new ArgumentError(`huodongxing limit must be <= ${MAX_LIMIT}`);\n  }\n  return limit;\n}\n\nfunction appendIfPresent(params, name, value) {\n  const text = cleanText(value);\n  if (text) params.set(name, text);\n}\n\nfunction dateOrdinal(year, month, day) {\n  return Math.floor(Date.UTC(year, month - 1, day) / 86400000);\n}\n\nfunction parseYmd(value) {\n  const match = cleanText(value).match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n  if (!match) return null;\n  const year = Number(match[1]);\n  const month = Number(match[2]);","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/huodongxing/events.js#L12-L48","documentation":"requireLimit caps the huodongxing events `limit` at MAX_LIMIT = 50 (defined in clis/huodongxing/events.js:5). Values above the cap — including valid integers like 51, 100, 1000 — throw this ArgumentError naming the maximum. The cap protects the underlying page scrape from requesting impractically large result sets.","triggerScenarios":"limit(100), limit('500'), limit(51) — any integer value greater than 50 on any call path routed through requireLimit (the events listing's limit option).","commonSituations":"Users expecting an unlimited/paginated fetch passing a large number; porting code from another API whose max page size is 100; generating limit from page-size math that exceeds the site's ceiling.","solutions":["Pass a limit of at most 50; omit the option to use the default 20.","Clamp at the call site: Math.min(Math.max(1, n), 50) before invoking.","If you need more than 50 events, paginate — call repeatedly (possibly with date filters via date/dateTo) and merge results."],"exampleFix":"// before\nawait events({ limit: 200 }); // ArgumentError: must be <= 50\n// after\nconst n = Math.min(Math.max(1, Number(userLimit) || 20), 50);\nawait events({ limit: n });","handlingStrategy":"validation","validationCode":"const MAX_LIMIT = 50;\nfunction clampLimit(value) {\n  const n = typeof value === 'number' ? value : Number(String(value ?? '').trim());\n  if (!Number.isInteger(n) || n <= 0) return 20;\n  return Math.min(n, MAX_LIMIT);\n}","typeGuard":"function isWithinLimit(v, max = 50) {\n  return Number.isInteger(v) && v > 0 && v <= max;\n}","tryCatchPattern":"try {\n  await events({ limit });\n} catch (err) {\n  if (err instanceof ArgumentError && /limit must be <= 50/.test(err.message)) {\n    await events({ limit: 50 }); // clamp to maximum\n  } else throw err;\n}","preventionTips":["Clamp user-supplied limits with Math.min(n, 50) at the boundary.","Remember the cap is 50 for this adapter — don't reuse page-size constants from other APIs.","For larger result sets, paginate with date filters instead of raising limit.","Document the maximum in your CLI's help text."],"tags":["argument-validation","limit-exceeded","cli"],"backgroundTag":"limit-exceeds-maximum","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}