{"record":{"id":"d2db848282ecc5b6","repo":"jackwener/OpenCLI","slug":"barchart-greeks-returned-a-malformed-option-row-id","errorCode":null,"errorMessage":"Barchart greeks returned a malformed option row identity","messagePattern":"Barchart greeks returned a malformed option row identity","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/barchart/greeks.js","lineNumber":183,"sourceCode":"            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,\n                expiration: expirationValue,\n            };\n        });\n    },\n});","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/barchart/greeks.js#L165-L201","documentation":"Thrown when a greeks row exists as an object but its identity fields are invalid: `type` is not call/put, `strike` is undefined/null/empty, or `expiration` is missing. These fields are required to identify each option contract, so the library refuses to return the row.","triggerScenarios":"Barchart rows missing `strike` or `expiration` keys, `type` values like 'C'/'P' or localized text that fail the /^(call|put)$/i check, or truncated rows in the scraped payload.","commonSituations":"Barchart schema changes renaming fields (e.g. `type` becoming `optionType`), strikes serialized as objects instead of scalars, rows for exotic/index options without a standard type label.","solutions":["Inspect the raw row to find which identity field is missing or renamed.","Normalize type values (map 'C'/'P' to 'call'/'put') before the check.","Update field-name mappings to the current Barchart schema.","Skip rows with incomplete identity instead of failing the entire request."],"exampleFix":"// before\nif (!/^(call|put)$/i.test(type) || r.strike === undefined || r.strike === null || r.strike === '' || !expirationValue) throw ...;\n// after\nconst normalizedType = { c: 'call', p: 'put' }[type.toLowerCase()] || type;\nif (!/^(call|put)$/i.test(normalizedType) || r.strike == null || r.strike === '' || !expirationValue) throw ...;","handlingStrategy":"validation","validationCode":"function rowIdentityOk(r){\n  const type = String(r.type||'').trim();\n  return /^(call|put|c|p)$/i.test(type) && r.strike != null && r.strike !== '' && !!String(r.expiration||'').trim();\n}","typeGuard":"const hasContractIdentity = (r) => /^(call|put)$/i.test(String(r?.type||'')) && r?.strike != null && !!String(r?.expiration||'').trim();","tryCatchPattern":"try {\n  const rows = await cli.run(['barchart','greeks', symbol]);\n} catch (e) {\n  if (e.message.includes('malformed option row identity')) {\n    // normalize type/strike/expiration field names, then retry\n  }\n}","preventionTips":["Normalize 'C'/'P' type codes to 'call'/'put' upstream","Map renamed Barchart fields to the expected schema","Skip rows lacking identity rather than failing the batch","Diff payloads against a known-good capture after Barchart changes"],"tags":["barchart","options","validation","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}