jackwener/OpenCLI · error · ArgumentError
coingecko page must be a positive integer
Error message
coingecko page must be a positive integer
What it means
The `coingecko exchanges` command requires `page` to be a positive integer (1-based) because it is sent verbatim as the `page` query parameter to CoinGecko's `/api/v3/exchanges` endpoint. The library converts `args.page` with `Number()` and rejects any value that is not an integer or is <= 0 with an ArgumentError, failing fast before any network call.
Source
Thrown at clis/coingecko/exchanges.js:32
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)',
'Free tier allows ~30 calls/min. Wait and retry.',
);
}
if (!resp.ok) {View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a page >= 1: `coingecko exchanges --page 1` (the default is already 1).
- Coerce and clamp in your calling code: `page = Math.max(1, Math.floor(Number(rawPage) || 1))`.
- If paginating from a 0-based loop index, add 1 before passing: `func({ page: i + 1 })`.
- Omit the argument entirely to use the built-in default of 1.
Example fix
// before
await exchanges.func({ page: 0 });
// after
await exchanges.func({ page: Math.max(1, Math.floor(Number(userPage) || 1)) }); Defensive patterns
Strategy: validation
Validate before calling
const page = Math.max(1, Math.floor(Number(rawPage) || 1));
if (!Number.isInteger(page) || page <= 0) throw new Error(`page must be a positive integer, got ${rawPage}`); Type guard
function isValidPage(v) { const n = Number(v); return Number.isInteger(n) && n > 0; } Prevention
- Always use 1-based page numbers with CoinGecko endpoints.
- Clamp/normalize user input with Math.max(1, Math.floor(...)) before calling.
- Rely on the built-in default (page=1) instead of hand-rolling 'first page' values.
- Sanitize CLI/env-derived strings with Number() before passing them as page.
When it happens
Trigger: Calling the exchanges command with page=0, page=-1, page=1.5, a non-numeric string like 'first' or '', or an object/array (Number() yields NaN) — e.g. `coingecko exchanges --page 0` or programmatic invocation `func({ page: 'two' })`.
Common situations: Scripts computing page numbers from loops that start at 0 instead of 1, passing user-supplied CLI text without sanitizing, off-by-one pagination math, or defaulting page to 0 as a 'first page' sentinel in another language's convention.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- 1688 item expects an offer URL or offer ID
- Invalid 1688 URL
- tid must be a numeric thread id
- kind
- direction
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3e641c1a9e66caf9.
Report an issue: GitHub.