jackwener/OpenCLI · error · ArgumentError
limit must be a positive integer
Error message
limit must be a positive integer
What it means
This ArgumentError is thrown before any network call when the limit argument, after Number() coercion, is not a positive integer (0, negative, NaN, fractional). The library enforces that per_page must be a valid positive integer because CoinGecko requires one. It fails fast so no request is wasted.
Source
Thrown at clis/coingecko/top.js:22
cli({
site: 'coingecko',
name: 'top',
access: 'read',
description: '按市值排序的加密货币行情(默认 USD)',
domain: 'api.coingecko.com',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'currency', type: 'string', default: 'usd', help: '计价币种 (usd / cny / eur / jpy ...)' },
{ name: 'limit', type: 'int', default: 10, help: '返回数量(默认 10,最多 250)' },
],
columns: ['rank', 'symbol', 'name', 'price', 'change24hPct', 'marketCap', 'volume24h', 'high24h', 'low24h'],
func: async (args) => {
const currency = String(args.currency ?? 'usd').toLowerCase();
const limit = Number(args.limit ?? 10);
if (!Number.isInteger(limit) || limit <= 0) {
throw new ArgumentError('limit must be a positive integer');
}
if (limit > 250) {
throw new ArgumentError('limit must be <= 250 (CoinGecko per_page upper bound)');
}
const url = new URL('https://api.coingecko.com/api/v3/coins/markets');
url.searchParams.set('vs_currency', currency);
url.searchParams.set('order', 'market_cap_desc');
url.searchParams.set('per_page', String(limit));
url.searchParams.set('page', '1');
url.searchParams.set('sparkline', 'false');
let resp;
try {
resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
} catch (error) {
throw new CommandExecutionError(`coingecko top request failed: ${error?.message || error}`);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a whole number >= 1, e.g. --limit 10 (the default).
- Check the shell/config value for typos, empty strings, or units ('20x').
- Coerce safely in your caller: limit = parseInt(raw, 10) and validate before invoking.
- If you need 'all coins', call repeatedly with per_page=250 and page=1..N instead of a huge limit.
Example fix
// before
await runCli('coingecko', 'top', ['--limit', process.env.TOP_N]);
// after
const n = parseInt(process.env.TOP_N ?? '10', 10);
if (!Number.isInteger(n) || n <= 0) throw new Error('TOP_N must be a positive integer');
await runCli('coingecko', 'top', ['--limit', String(n)]); Defensive patterns
Strategy: validation
Validate before calling
function parseLimit(raw) {
const n = Number(raw);
if (!Number.isInteger(n) || n <= 0) throw new Error(`limit must be a positive integer, got ${JSON.stringify(raw)}`);
return n;
}
const limit = parseLimit(args.limit ?? 10); Type guard
function isPositiveInt(v) { return Number.isInteger(v) && v > 0; } Try / catch
try {
rows = await runCli('coingecko', 'top', ['--limit', limit]);
} catch (e) {
if (/limit must be a positive integer/.test(e.message)) {
console.error('Bad --limit; using default 10');
rows = await runCli('coingecko', 'top', ['--limit', '10']);
} else throw e;
} Prevention
- Use parseInt(value, 10) and check isNaN before passing limits
- Sanitize environment/config values that feed --limit
- Never pass raw user strings straight through to numeric args
- Add input validation at the CLI/script boundary
When it happens
Trigger: --limit 0, --limit -5, --limit 2.5, --limit 'abc' (Number('abc') = NaN fails Number.isInteger), or limit omitted and a default of 0/undefined leaking in from a caller.
Common situations: Shell variables interpolating empty strings ('' -> 0? actually '' -> 0 via Number, fails); typos like 'l0'; passing floats from scripted calls; config files with limit: null becoming NaN? (Number(null)=0, non-positive).
Related errors
- series_id must be a non-empty value
- Invalid Chess.com username "${value}" Usernames are 3-25 cha
- coingecko derivatives limit must be a positive integer
- Search keyword cannot be empty
- ${label} must be a positive integer
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/f6588930e7a3e5d7.
Report an issue: GitHub.