{"record":{"id":"f76bf63c9131919c","repo":"jackwener/OpenCLI","slug":"coingecko-limit-must-be-250-per-page-upper-bou","errorCode":null,"errorMessage":"coingecko limit must be <= 250 (per_page upper bound)","messagePattern":"coingecko limit must be <= 250 \\(per_page upper bound\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/coingecko/exchanges.js","lineNumber":28,"sourceCode":"    site: 'coingecko',\n    name: 'exchanges',\n    access: 'read',\n    description: 'Top crypto exchanges by 24h BTC trading volume',\n    domain: 'api.coingecko.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'limit', type: 'int', default: 20, help: 'Number of exchanges (1-250, CoinGecko per_page upper bound)' },\n        { name: 'page', type: 'int', default: 1, help: 'Page number (1-based)' },\n    ],\n    columns: ['rank', 'id', 'name', 'trustScore', 'volume24hBtc', 'country', 'yearEstablished', 'url'],\n    func: async (args) => {\n        const limit = Number(args.limit ?? 20);\n        if (!Number.isInteger(limit) || limit <= 0) {\n            throw new ArgumentError('coingecko limit must be a positive integer');\n        }\n        if (limit > 250) {\n            throw new ArgumentError('coingecko limit must be <= 250 (per_page upper bound)');\n        }\n        const page = Number(args.page ?? 1);\n        if (!Number.isInteger(page) || page <= 0) {\n            throw new ArgumentError('coingecko page must be a positive integer');\n        }\n        const url = new URL('https://api.coingecko.com/api/v3/exchanges');\n        url.searchParams.set('per_page', String(limit));\n        url.searchParams.set('page', String(page));\n        let resp;\n        try {\n            resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`coingecko exchanges request failed: ${err?.message ?? err}`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError(\n                'coingecko returned HTTP 429 (rate limited)',","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coingecko/exchanges.js#L10-L46","documentation":"ArgumentError thrown when the --limit for coingecko exchanges exceeds 250, the maximum per_page value CoinGecko's /exchanges endpoint accepts. The library rejects it client-side before making the request to avoid a guaranteed API error.","triggerScenarios":"Passing --limit 251 or higher, or programmatically computing a limit like Infinity/1e6 intending 'everything' when running the exchanges command.","commonSituations":"Trying to fetch all exchanges in one call; scripts using Number.MAX_SAFE_INTEGER as a sentinel for 'unlimited'; forgetting that CoinGecko caps per_page at 250 and requires pagination for more.","solutions":["Lower the limit to <= 250, e.g. --limit 250.","To get more than 250 exchanges, pass --page 2, --page 3, etc. (per_page=limit per page).","Replace 'unlimited' sentinel values in scripts with an explicit capped value plus pagination.","Compute pagesNeeded = Math.ceil(total/limit) in your tooling instead of inflating limit."],"exampleFix":"// before\nrunCli(['coingecko', 'exchanges', '--limit', '1000']);\n// after\nrunCli(['coingecko', 'exchanges', '--limit', '250', '--page', '1']);\nrunCli(['coingecko', 'exchanges', '--limit', '250', '--page', '2']);","handlingStrategy":"validation","validationCode":"const n = Number(limit);\nif (!Number.isInteger(n) || n <= 0 || n > 250) {\n  throw new RangeError(`limit must be 1-250 (CoinGecko per_page cap), got ${n}`);\n}","typeGuard":"function isWithinPerPageCap(v) {\n  const n = Number(v);\n  return Number.isInteger(n) && n >= 1 && n <= 250;\n}","tryCatchPattern":"try {\n  return await runCli(['coingecko', 'exchanges', '--limit', String(limit)]);\n} catch (err) {\n  if (String(err.message).includes('limit must be <= 250')) {\n    return runCli(['coingecko', 'exchanges', '--limit', '250', '--page', '1']);\n  }\n  throw err;\n}","preventionTips":["Cap any user/supplied limit at 250 before calling the CLI.","Use --page for datasets larger than 250 instead of inflating limit.","Replace 'unlimited' sentinel values (Infinity, MAX_SAFE_INTEGER) with pagination logic.","Remember CoinGecko's per_page maximum is a documented API constraint."],"tags":["argument-validation","pagination","limits","api-constraint","coingecko"],"backgroundTag":"api-rate-or-limit-exceeded","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}