{"record":{"id":"6b4480ecd7f6bb36","repo":"jackwener/OpenCLI","slug":"coingecko-returned-error-data-error","errorCode":null,"errorMessage":"coingecko returned error: ${data.error}","messagePattern":"coingecko returned error: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/coingecko/coin.js","lineNumber":69,"sourceCode":"            throw new CommandExecutionError(`coingecko coin request failed: ${error?.message || error}`);\n        }\n        if (resp.status === 404) {\n            throw new EmptyResultError('coingecko coin', `coingecko has no coin with id \"${id}\".`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError('coingecko returned HTTP 429 (rate limited)', 'Free tier allows ~30 calls/min. Wait and retry.');\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`coingecko coin failed: HTTP ${resp.status}`);\n        }\n        let data;\n        try {\n            data = await resp.json();\n        } catch (error) {\n            throw new CommandExecutionError(`coingecko returned malformed JSON: ${error?.message || error}`);\n        }\n        if (data?.error) {\n            throw new CommandExecutionError(`coingecko returned error: ${data.error}`);\n        }\n\n        const md = data.market_data || {};\n        const pick = (obj, key) => (obj && obj[key] != null ? obj[key] : null);\n        const isoFromMaybe = (s) => (s ? String(s).slice(0, 10) : '');\n        const price = pick(md.current_price, currency);\n        const marketCap = pick(md.market_cap, currency);\n        const volume24h = pick(md.total_volume, currency);\n        if (price == null && marketCap == null && volume24h == null) {\n            throw new CommandExecutionError(\n                `coingecko returned no market data for currency \"${currency}\"`,\n                'Use a CoinGecko-supported quote currency such as usd, cny, eur, or jpy.',\n            );\n        }\n\n        return [{\n            id: data.id || id,\n            symbol: String(data.symbol || '').toUpperCase(),","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coingecko/coin.js#L51-L87","documentation":"This CommandExecutionError is thrown when the parsed JSON body contains a truthy `error` field. CoinGecko sometimes signals API-level failures inside a 200/JSON body (e.g. status/error objects for invalid parameters or plan restrictions), and this branch surfaces that embedded error message directly to the caller.","triggerScenarios":"CoinGecko responding with JSON containing an `error` key — e.g. internal API errors, plan/endpoint restrictions, or deprecated-parameter responses wrapped in a 2xx status.","commonSituations":"Endpoint behavior changes or plan gating on CoinGecko's side; hitting an endpoint variant with different auth requirements; transient CoinGecko internal errors returned in-body.","solutions":["Read the embedded error text in the message — it usually names the exact API-side problem","Retry after a delay if it looks transient (CoinGecko internal error)","Verify the command/parameters against current CoinGecko API v3 docs in case the endpoint contract changed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"null","typeGuard":"const hasEmbeddedApiError = (data) => data != null && typeof data === 'object' && 'error' in data && data.error != null;","tryCatchPattern":"try { const rows = await run(['coingecko', 'coin', id]); } catch (e) { if (/coingecko returned error:/.test(e.message)) { console.error('API-side error:', e.message); return retryLaterIfTransient(e); } throw e; }","preventionTips":["Surface the embedded error text to diagnose plan/endpoint restrictions","Keep the CLI and its endpoint usage aligned with current CoinGecko v3 docs","Retry with backoff only for transient-looking errors; escalate persistent ones"],"tags":["api-error","api-response","response-body"],"backgroundTag":"api-error-in-response-body","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}