{"record":{"id":"e7ce92052741bb42","repo":"jackwener/OpenCLI","slug":"barchart-greeks-returned-a-malformed-option-row","errorCode":null,"errorMessage":"Barchart greeks returned a malformed option row","messagePattern":"Barchart greeks returned a malformed option row","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/barchart/greeks.js","lineNumber":178,"sourceCode":"                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,\n                delta: r.delta != null ? Number(Number(r.delta).toFixed(4)) : null,\n                gamma: r.gamma != null ? Number(Number(r.gamma).toFixed(4)) : null,\n                theta: r.theta != null ? Number(Number(r.theta).toFixed(4)) : null,\n                vega: r.vega != null ? Number(Number(r.vega).toFixed(4)) : null,\n                rho: r.rho != null ? Number(Number(r.rho).toFixed(4)) : null,\n                volume: r.volume,\n                openInterest: r.openInterest,","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/barchart/greeks.js#L160-L196","documentation":"Thrown while mapping Barchart greek rows when an individual row is not a plain object (null, non-object, or an array). The library treats each row as a record with type/strike/expiration fields; a row violating that shape aborts the whole command with this CommandExecutionError.","triggerScenarios":"Barchart returning rows containing null placeholders, or a payload where `rows` is an array of arrays/strings instead of objects after a schema change.","commonSituations":"Partial page renders during scraping, Barchart API format drift, mixing cached and fresh payloads, rows padded with nulls for illiquid strikes.","solutions":["Log the offending row to see the actual shape Barchart returned.","Filter out non-object rows before mapping.","Update the CLI to match the current Barchart row schema.","Retry after re-authenticating if a degraded/scraped page was served."],"exampleFix":"// before\nreturn data.rows.map(r => { if (!r || typeof r !== 'object' || Array.isArray(r)) throw ...; });\n// after\nreturn data.rows.filter(r => r && typeof r === 'object' && !Array.isArray(r)).map(r => { /* map fields */ });","handlingStrategy":"type-guard","validationCode":"const validRow = (r) => r && typeof r === 'object' && !Array.isArray(r);\nrows.filter(validRow).map(/* ... */);","typeGuard":"const isOptionRow = (r) => typeof r === 'object' && r !== null && !Array.isArray(r);","tryCatchPattern":"try {\n  const rows = await cli.run(['barchart','greeks', symbol]);\n} catch (e) {\n  if (e.message.includes('malformed option row')) {\n    // dump and sanitize rows, skip bad entries, retry\n  }\n}","preventionTips":["Sanitize/filter rows before mapping","Keep the CLI updated for Barchart schema drift","Log the raw payload when a row fails validation","Treat scraping output as untrusted input"],"tags":["barchart","options","row-validation","schema"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}