jackwener/OpenCLI · error · CommandExecutionError

coingecko global returned no data envelope

Error message

coingecko global returned no data envelope

What it means

This CommandExecutionError is thrown when the /global response parses as JSON but lacks the expected { data: {...} } envelope. The library treats a missing 'data' object as an unusable response rather than trying to guess fields. It indicates the API's response shape changed or returned a JSON error payload.

Source

Thrown at clis/coingecko/global.js:48

        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 global returned HTTP ${resp.status}`);
        }
        let body;
        try {
            body = await resp.json();
        }
        catch (err) {
            throw new CommandExecutionError(`coingecko global returned malformed JSON: ${err?.message ?? err}`);
        }
        const data = body?.data;
        if (!data) {
            throw new CommandExecutionError('coingecko global returned no data envelope');
        }
        const totalMarketCap = data?.total_market_cap?.[currency];
        const totalVolume = data?.total_volume?.[currency];
        if (totalMarketCap == null && totalVolume == null) {
            throw new ArgumentError(
                `coingecko has no market totals for currency "${currency}"`,
                'Use a CoinGecko-supported quote currency such as usd, cny, eur, or jpy.',
            );
        }
        return [{
            currency: currency.toUpperCase(),
            totalMarketCap: totalMarketCap != null ? Number(totalMarketCap) : null,
            totalVolume24h: totalVolume != null ? Number(totalVolume) : null,
            marketCapChange24hPct: data.market_cap_change_percentage_24h_usd != null ? Number(data.market_cap_change_percentage_24h_usd) : null,
            btcDominancePct: data?.market_cap_percentage?.btc != null ? Number(data.market_cap_percentage.btc) : null,
            ethDominancePct: data?.market_cap_percentage?.eth != null ? Number(data.market_cap_percentage.eth) : null,
            activeCryptocurrencies: data.active_cryptocurrencies != null ? Number(data.active_cryptocurrencies) : null,
            markets: data.markets != null ? Number(data.markets) : null,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Print the raw body (curl the endpoint) to see what JSON was actually returned.
  2. Check CoinGecko API status/changelog for schema changes to /global.
  3. If an API error envelope is returned, address the underlying cause (quota, auth, blocked IP).
  4. Pin or update the opencli library version so its parsing matches the current API schema.
  5. Retry later if CoinGecko is mid-incident; envelope-less responses are often transient.

Example fix

// before
const body = JSON.parse(raw);
const caps = body.total_market_cap;
// after
const data = body?.data;
if (!data) throw new Error('unexpected /global envelope: ' + JSON.stringify(body).slice(0, 200));
const caps = data.total_market_cap;
Defensive patterns

Strategy: type-guard

Validate before calling

const probe = await fetch('https://api.coingecko.com/api/v3/global').then(r => r.json());
if (!probe?.data) console.warn('coingecko /global envelope missing — API shape may have changed');

Type guard

function hasGlobalEnvelope(body) {
  return typeof body === 'object' && body !== null && 'data' in body && typeof body.data === 'object';
}

Try / catch

try {
  rows = await runCli('coingecko', 'global');
} catch (e) {
  if (String(e.message).includes('no data envelope')) {
    console.error('API schema drift or JSON error payload — inspect raw response');
  }
  throw e;
}

Prevention

When it happens

Trigger: resp.json() succeeded but body?.data is undefined/null: the API returned a JSON error object, an empty body ('{}'), or a restructured payload without the 'data' wrapper.

Common situations: CoinGecko deprecating or changing the /global schema; a transparent proxy returning its own JSON error (e.g. quota exhausted JSON); API returning {status:{error_code:...}} error envelopes for rejected requests.

Related errors


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