{"record":{"id":"0f39d833187616e0","repo":"jackwener/OpenCLI","slug":"coingecko-trending-failed-http-resp-status","errorCode":null,"errorMessage":"coingecko trending failed: HTTP ${resp.status}","messagePattern":"coingecko trending failed: HTTP (.+?)","errorType":"http","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/coingecko/trending.js","lineNumber":30,"sourceCode":"    description: 'Top trending cryptocurrencies on CoinGecko in the last 24h (search-volume based).',\n    domain: 'api.coingecko.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [],\n    columns: ['rank', 'id', 'symbol', 'name', 'marketCapRank', 'priceBtc', 'thumb'],\n    func: async () => {\n        const url = 'https://api.coingecko.com/api/v3/search/trending';\n        let resp;\n        try {\n            resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });\n        } catch (error) {\n            throw new CommandExecutionError(`coingecko trending request failed: ${error?.message || error}`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError('coingecko returned HTTP 429 (rate limited)', 'Wait and retry.');\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`coingecko trending 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        const coins = Array.isArray(data?.coins) ? data.coins : [];\n        if (coins.length === 0) {\n            throw new EmptyResultError('coingecko trending', 'coingecko returned no trending coins.');\n        }\n        return coins.map((entry, i) => {\n            const c = entry?.item || {};\n            return {\n                rank: i + 1,\n                id: c.id || '',\n                symbol: String(c.symbol || '').toUpperCase(),\n                name: c.name || '',","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coingecko/trending.js#L12-L48","documentation":"This CommandExecutionError is thrown when the CoinGecko trending endpoint returns a response whose status is not OK and not 429 — i.e. any other HTTP error status (403, 500, 502, 503, etc.). The message interpolates the actual status code so the developer can see exactly what the server returned. It comes after the fetch succeeded but the server rejected or failed the request at the HTTP layer.","triggerScenarios":"`resp.ok` is false and `resp.status !== 429` after fetching https://api.coingecko.com/api/v3/search/trending. Typical statuses: 403 (blocked/WAF, often when the User-Agent heuristic is rejected by Cloudflare), 500/502/503 (CoinGecko server-side issues), 404 if the API path changed.","commonSituations":"CoinGecko outage or degraded service returning 5xx, Cloudflare bot protection challenging requests with the spoofed Mozilla/5.0 UA (403), corporate proxies injecting error pages, or CoinGecko deprecating/renaming the API path.","solutions":["Check the interpolated HTTP status in the message: 5xx means wait/retry (server-side), 403 means your client is being blocked","If 403, test with curl using a full realistic User-Agent; consider CoinGecko's official API with a key instead of the spoofed-UA public endpoint","Check https://status.coingecko.com for outages causing 5xx responses","Add retry-with-backoff around the command for transient 5xx responses"],"exampleFix":"null","handlingStrategy":"retry","validationCode":"null","typeGuard":"function isHttpError(e) {\n  const m = /HTTP (\\d{3})/.exec(e?.message || '');\n  return m ? { status: Number(m[1]), isServer: Number(m[1]) >= 500, isForbidden: m[1] === '403' } : null;\n}","tryCatchPattern":"try {\n  await runCli('coingecko trending');\n} catch (e) {\n  const st = isHttpError(e);\n  if (st?.isServer) return retryWithBackoff(() => runCli('coingecko trending'));\n  if (st?.isForbidden) throw new Error('Blocked by CoinGecko/Cloudflare: use official API with key');\n  throw e;\n}","preventionTips":["Distinguish 5xx (retryable) from 403 (blocked) via the status in the message","For 403, stop spoofing User-Agent and use the official CoinGecko API with a key","Monitor status.coingecko.com for 5xx outages","Add retry with backoff for transient server errors"],"tags":["http-error","api-response","coingecko","cli"],"backgroundTag":"http-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}