jackwener/OpenCLI · error · CommandExecutionError

coingecko exchanges request failed: ${err?.message ?? err}

Error message

coingecko exchanges request failed: ${err?.message ?? err}

What it means

This CommandExecutionError wraps any network-level failure of the fetch() call to https://api.coingecko.com/api/v3/exchanges — DNS resolution failure, connection refused/reset, TLS errors, or request aborts. The original error's message is interpolated so the underlying cause (e.g. 'getaddrinfo ENOTFOUND') is preserved in the message.

Source

Thrown at clis/coingecko/exchanges.js:42

        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) {
            throw new CommandExecutionError(`coingecko exchanges returned HTTP ${resp.status}`);
        }
        let data;
        try {
            data = await resp.json();
        }
        catch (err) {
            throw new CommandExecutionError(`coingecko exchanges returned malformed JSON: ${err?.message ?? err}`);
        }
        if (!Array.isArray(data) || !data.length) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check network connectivity: `curl -I https://api.coingecko.com/api/v3/ping` to see if the host is reachable at all.
  2. Fix DNS or proxy configuration (set HTTPS_PROXY, corporate proxy, or /etc/hosts) and retry.
  3. Inspect the embedded cause in the message (e.g. ENOTFOUND vs ECONNREFUSED) to target the right fix.
  4. Add retry with backoff in your wrapper for transient network errors, since this command is a single-shot fetch.
  5. If behind a strict firewall, allowlist api.coingecko.com or run from a machine with egress.
Defensive patterns

Strategy: retry

Try / catch

try {
  const rows = await exchanges.func({ page: 1 });
} catch (e) {
  if (/coingecko exchanges request failed/.test(e.message)) {
    // network-level failure: retry with backoff
    await sleep(2000);
    return withRetry(() => exchanges.func({ page: 1 }), 3);
  }
  throw e;
}

Prevention

When it happens

Trigger: fetch() throws before an HTTP response exists: no network connectivity, DNS cannot resolve api.coingecko.com, an offline/air-gapped environment, a proxy blocking the request, TLS interception, or the process aborting the fetch.

Common situations: Running the CLI in CI containers without egress, corporate firewalls/proxies blocking api.coingecko.com, VPN drops mid-request, or DNS misconfiguration in Docker/Kubernetes environments.

Related errors


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