{"record":{"id":"af7256fe104d79f4","repo":"jackwener/OpenCLI","slug":"coingecko-derivatives-returned-http-resp-status","errorCode":null,"errorMessage":"coingecko derivatives returned HTTP ${resp.status}","messagePattern":"coingecko derivatives returned HTTP (.+?)","errorType":"http","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/coingecko/derivatives.js","lineNumber":50,"sourceCode":"        if (limit > 500) {\n            throw new ArgumentError('coingecko derivatives limit must be <= 500');\n        }\n        const filter = args.symbol == null ? '' : String(args.symbol).trim().toUpperCase();\n        let resp;\n        try {\n            resp = await fetch(ENDPOINT, { headers: { 'User-Agent': 'Mozilla/5.0' } });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`coingecko derivatives request failed: ${err?.message ?? err}`);\n        }\n        if (resp.status === 429) {\n            throw new CommandExecutionError(\n                'coingecko derivatives returned HTTP 429 (rate limited)',\n                'Free tier allows ~30 calls/min. Wait and retry.',\n            );\n        }\n        if (!resp.ok) {\n            throw new CommandExecutionError(`coingecko derivatives returned HTTP ${resp.status}`);\n        }\n        let data;\n        try {\n            data = await resp.json();\n        }\n        catch (err) {\n            throw new CommandExecutionError(`coingecko derivatives returned malformed JSON: ${err?.message ?? err}`);\n        }\n        if (!Array.isArray(data) || !data.length) {\n            throw new EmptyResultError('coingecko derivatives', 'CoinGecko returned no derivative tickers.');\n        }\n        let rows = data;\n        if (filter) {\n            rows = data.filter((d) => String(d.symbol ?? '').toUpperCase().includes(filter)\n                || String(d.index_id ?? '').toUpperCase().includes(filter));\n            if (!rows.length) {\n                throw new EmptyResultError('coingecko derivatives', `No derivative tickers matched symbol=\"${filter}\".`);\n            }","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coingecko/derivatives.js#L32-L68","documentation":"This CommandExecutionError is thrown when CoinGecko's /derivatives endpoint returns any non-2xx status other than 429 (which is handled separately), e.g. 404, 500, or 502/503 from CoinGecko or an intermediary. It surfaces the raw HTTP status so the caller can react.","triggerScenarios":"CoinGecko server-side errors (5xx), endpoint removed/moved (404), gateway errors from CDN (502/503), or an unexpected 4xx like 401 if the endpoint later requires auth.","commonSituations":"CoinGecko outages or degraded service, API version/URL changes breaking the ENDPOINT path, CDN incidents, maintenance windows.","solutions":["Check the specific status: 5xx means retry later; 404 suggests the endpoint path changed","Check CoinGecko status page (status.coingecko.com) for incidents","Verify the ENDPOINT URL is still valid per current CoinGecko API docs","Add retry with backoff for transient 5xx/503 responses"],"exampleFix":"// before\n// assuming endpoint always works\nfetch('https://api.coingecko.com/api/v3/derivatives')\n// after\n// verify path against docs and retry on 5xx\nconst resp = await fetch(ENDPOINT);\nif (resp.status >= 500) await retryWithBackoff(() => fetch(ENDPOINT));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if (!resp.ok) {\n  if (resp.status >= 500 || resp.status === 503) {\n    // transient: retry with backoff\n    resp = await retryWithBackoff(() => fetch(ENDPOINT), { retries: 3 });\n  } else {\n    throw new CommandExecutionError(`coingecko derivatives returned HTTP ${resp.status}`);\n  }\n}","preventionTips":["Monitor the CoinGecko status page for incidents","Pin/verify the endpoint path against current API docs","Implement retry-with-backoff for 5xx/503 responses","Handle non-2xx statuses explicitly rather than assuming resp.json() will succeed"],"tags":["http","http-status","api","server-error"],"backgroundTag":"http-error-status","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}