{"record":{"id":"cff040d95dc55adb","repo":"jackwener/OpenCLI","slug":"barchart-greeks-returned-an-unreadable-options-pay-cff040","errorCode":null,"errorMessage":"Barchart greeks returned an unreadable options payload","messagePattern":"Barchart greeks returned an unreadable options payload","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/barchart/greeks.js","lineNumber":171,"sourceCode":"        } catch(e) {\n          return { ok: false, reason: 'exception', message: e?.message || String(e) };\n        }\n      })()\n    `));\n        if (!data || data.ok !== true) {\n            if (data?.reason === 'http') {\n                throw new CommandExecutionError(`Barchart greeks request failed: HTTP ${data.status}${data.statusText ? ` ${data.statusText}` : ''}`);\n            }\n            if (data?.reason === 'malformed') {\n                throw new CommandExecutionError(`Barchart greeks returned an unreadable options payload${data.message ? `: ${data.message}` : ''}`);\n            }\n            if (data?.reason === 'exception') {\n                throw new CommandExecutionError(`Barchart greeks request failed: ${data.message || 'unknown error'}`);\n            }\n            throw new CommandExecutionError(`Failed to fetch Barchart greeks for ${symbol}`);\n        }\n        if (!Array.isArray(data.rows)) {\n            throw new CommandExecutionError('Barchart greeks returned an unreadable options payload');\n        }\n        if (data.rows.length === 0) {\n            throw new EmptyResultError('barchart greeks', `No option greeks were returned for ${symbol}. Confirm the symbol, expiration, and Barchart login state.`);\n        }\n        return data.rows.map(r => {\n            if (!r || typeof r !== 'object' || Array.isArray(r)) {\n                throw new CommandExecutionError('Barchart greeks returned a malformed option row');\n            }\n            const type = String(r.type || '').trim();\n            const expirationValue = String(r.expiration || '').trim();\n            if (!/^(call|put)$/i.test(type) || r.strike === undefined || r.strike === null || r.strike === '' || !expirationValue) {\n                throw new CommandExecutionError('Barchart greeks returned a malformed option row identity');\n            }\n            return {\n                type,\n                strike: r.strike,\n                last: r.last != null ? Number(Number(r.last).toFixed(2)) : null,\n                iv: r.iv != null ? Number(Number(r.iv).toFixed(2)) + '%' : null,","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/barchart/greeks.js#L153-L189","documentation":"Thrown by the barchart greeks command when the fetched Barchart options payload parses but does not contain a `rows` array (`Array.isArray(data.rows)` fails). The library expects the scraped/JSON response to expose option-greek rows; anything else (HTML login page, object with different keys, string) is treated as an unreadable payload. It signals the response shape diverged from the expected contract.","triggerScenarios":"Calling `barchart greeks <symbol>` when Barchart returns a login/consent page instead of JSON, when the internal data object uses a different key than `rows`, or when a proxy/captcha page replaces the payload.","commonSituations":"Expired Barchart session cookie, Barchart site redesign changing the JSON schema, scraping through a captive portal or corporate proxy that injects HTML, symbol routed to a page without options data.","solutions":["Re-authenticate with Barchart (refresh login state/cookies) and retry the command.","Log the raw response body to inspect what Barchart actually returned.","Verify the symbol actually has listed options (e.g. SPY vs a delisted ticker).","Update the CLI/library in case Barchart changed its payload schema."],"exampleFix":"// before\nconst data = JSON.parse(body);\nif (!Array.isArray(data.rows)) throw ...;\n// after\nconst data = typeof body === 'string' && body.trim().startsWith('<') ? null : JSON.parse(body);\nif (!data || !Array.isArray(data.rows)) throw new CommandExecutionError('Barchart greeks returned an unreadable options payload');","handlingStrategy":"type-guard","validationCode":"function hasGreeksPayload(d){ return d && typeof d === 'object' && Array.isArray(d.rows); }\n// run after fetching, before calling the CLI mapper","typeGuard":"const isGreeksPayload = (d) => !!d && typeof d === 'object' && !Array.isArray(d) && Array.isArray(d.rows);","tryCatchPattern":"try {\n  const rows = await cli.run(['barchart','greeks', symbol]);\n} catch (e) {\n  if (e.message.includes('unreadable options payload')) {\n    // inspect raw response / re-authenticate with Barchart\n  }\n}","preventionTips":["Keep Barchart session cookies fresh","Detect HTML responses before JSON.parse","Pin and update the CLI when Barchart changes its schema","Log raw payloads on failure for diagnosis"],"tags":["barchart","options","payload-shape","scraping"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}