jackwener/OpenCLI · error · CommandExecutionError
coingecko derivatives returned malformed JSON: ${err?.messag
Error message
coingecko derivatives returned malformed JSON: ${err?.message ?? err} What it means
The coingecko derivatives command wraps the response body parse of GET https://api.coingecko.com/api/v3/derivatives in a try/catch. When resp.json() rejects (body is not valid JSON), it rethrows a CommandExecutionError with the underlying parse message. The library throws this because the HTTP request itself succeeded (status was ok), but the payload could not be decoded.
Source
Thrown at clis/coingecko/derivatives.js:57
}
catch (err) {
throw new CommandExecutionError(`coingecko derivatives request failed: ${err?.message ?? err}`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
'coingecko derivatives returned HTTP 429 (rate limited)',
'Free tier allows ~30 calls/min. Wait and retry.',
);
}
if (!resp.ok) {
throw new CommandExecutionError(`coingecko derivatives returned HTTP ${resp.status}`);
}
let data;
try {
data = await resp.json();
}
catch (err) {
throw new CommandExecutionError(`coingecko derivatives returned malformed JSON: ${err?.message ?? err}`);
}
if (!Array.isArray(data) || !data.length) {
throw new EmptyResultError('coingecko derivatives', 'CoinGecko returned no derivative tickers.');
}
let rows = data;
if (filter) {
rows = data.filter((d) => String(d.symbol ?? '').toUpperCase().includes(filter)
|| String(d.index_id ?? '').toUpperCase().includes(filter));
if (!rows.length) {
throw new EmptyResultError('coingecko derivatives', `No derivative tickers matched symbol="${filter}".`);
}
}
return rows.slice(0, limit).map((d, i) => ({
rank: i + 1,
market: String(d.market ?? ''),
symbol: String(d.symbol ?? ''),
indexId: String(d.index_id ?? ''),
contractType: String(d.contract_type ?? ''),View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command after a short wait — transient CDN/proxy hiccups often resolve on their own.
- Check the raw response with curl -s https://api.coingecko.com/api/v3/derivatives | head -c 200 to see what body is actually returned.
- Disable or bypass intercepting proxies/VPNs (check HTTP(S)_PROXY env vars) that may inject HTML pages.
- Reduce request frequency to avoid Cloudflare bot challenges; consider a CoinGecko Pro API key.
- Verify network/DNS allows reaching api.coingecko.com directly.
Example fix
// before — caller assumes success means JSON
const data = await runCli(['coingecko', 'derivatives']);
// after
try {
const data = await runCli(['coingecko', 'derivatives']);
} catch (err) {
if (String(err.message).includes('malformed JSON')) {
await sleep(1000); // transient HTML/Cloudflare page — retry
return retryDerivatives();
}
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
const resp = await fetch('https://api.coingecko.com/api/v3/derivatives');
const text = await resp.text();
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
try { JSON.parse(text); } catch { console.warn('Non-JSON body, likely HTML challenge/proxy page'); } Type guard
function isDerivativeArray(v) {
return Array.isArray(v) && v.every((d) => d != null && typeof d === 'object' && 'symbol' in d);
} Try / catch
try {
const rows = await runCli(['coingecko', 'derivatives']);
} catch (err) {
if (String(err.message).includes('malformed JSON')) {
return retryWithBackoff(() => runCli(['coingecko', 'derivatives']), 3);
}
throw err;
} Prevention
- Retry with backoff on malformed JSON — usually a transient HTML/CDN page.
- Bypass suspicious proxies/VPNs; check HTTP(S)_PROXY env vars.
- Keep request rate low to avoid Cloudflare bot challenges.
- Inspect the raw body (curl) when it recurs to identify the interceptor.
When it happens
Trigger: CoinGecko returns HTTP 200 with a non-JSON body — e.g. an HTML Cloudflare challenge/interstitial page, a proxy/captive-portal interception page, a truncated or empty response body, or a maintenance error page served with a 2xx status.
Common situations: Corporate proxies or VPNs injecting an HTML block page; CoinGecko serving a Cloudflare 'checking your browser' page to the CLI's User-Agent; network middleboxes truncating the response mid-stream; CDN outage returning garbage.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- 12306 queryByTrainNo returned non-JSON body
- 12306 ${endpoint} returned non-JSON body
- coingecko global returned malformed JSON: ${err?.message ??
- coingecko returned malformed JSON: ${error?.message || error
- ${label} returned malformed JSON: ${err?.message ?? err}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/22d14df7d4163a01.
Report an issue: GitHub.