jackwener/OpenCLI · error · ArgumentError

coingecko limit must be <= 250 (per_page upper bound)

Error message

coingecko limit must be <= 250 (per_page upper bound)

What it means

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.

Source

Thrown at clis/coingecko/exchanges.js:28

    site: 'coingecko',
    name: 'exchanges',
    access: 'read',
    description: 'Top crypto exchanges by 24h BTC trading volume',
    domain: 'api.coingecko.com',
    strategy: Strategy.PUBLIC,
    browser: false,
    args: [
        { name: 'limit', type: 'int', default: 20, help: 'Number of exchanges (1-250, CoinGecko per_page upper bound)' },
        { name: 'page', type: 'int', default: 1, help: 'Page number (1-based)' },
    ],
    columns: ['rank', 'id', 'name', 'trustScore', 'volume24hBtc', 'country', 'yearEstablished', 'url'],
    func: async (args) => {
        const limit = Number(args.limit ?? 20);
        if (!Number.isInteger(limit) || limit <= 0) {
            throw new ArgumentError('coingecko limit must be a positive integer');
        }
        if (limit > 250) {
            throw new ArgumentError('coingecko limit must be <= 250 (per_page upper bound)');
        }
        const page = Number(args.page ?? 1);
        if (!Number.isInteger(page) || page <= 0) {
            throw new ArgumentError('coingecko page must be a positive integer');
        }
        const url = new URL('https://api.coingecko.com/api/v3/exchanges');
        url.searchParams.set('per_page', String(limit));
        url.searchParams.set('page', String(page));
        let resp;
        try {
            resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
        }
        catch (err) {
            throw new CommandExecutionError(`coingecko exchanges request failed: ${err?.message ?? err}`);
        }
        if (resp.status === 429) {
            throw new CommandExecutionError(
                'coingecko returned HTTP 429 (rate limited)',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Lower the limit to <= 250, e.g. --limit 250.
  2. To get more than 250 exchanges, pass --page 2, --page 3, etc. (per_page=limit per page).
  3. Replace 'unlimited' sentinel values in scripts with an explicit capped value plus pagination.
  4. Compute pagesNeeded = Math.ceil(total/limit) in your tooling instead of inflating limit.

Example fix

// before
runCli(['coingecko', 'exchanges', '--limit', '1000']);
// after
runCli(['coingecko', 'exchanges', '--limit', '250', '--page', '1']);
runCli(['coingecko', 'exchanges', '--limit', '250', '--page', '2']);
Defensive patterns

Strategy: validation

Validate before calling

const n = Number(limit);
if (!Number.isInteger(n) || n <= 0 || n > 250) {
  throw new RangeError(`limit must be 1-250 (CoinGecko per_page cap), got ${n}`);
}

Type guard

function isWithinPerPageCap(v) {
  const n = Number(v);
  return Number.isInteger(n) && n >= 1 && n <= 250;
}

Try / catch

try {
  return await runCli(['coingecko', 'exchanges', '--limit', String(limit)]);
} catch (err) {
  if (String(err.message).includes('limit must be <= 250')) {
    return runCli(['coingecko', 'exchanges', '--limit', '250', '--page', '1']);
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing --limit 251 or higher, or programmatically computing a limit like Infinity/1e6 intending 'everything' when running the exchanges command.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f76bf63c9131919c. Report an issue: GitHub.