jackwener/OpenCLI · error · CommandExecutionError

Barchart greeks returned a malformed option row identity

Error message

Barchart greeks returned a malformed option row identity

What it means

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.

Solutions

  1. Inspect the raw row to find which identity field is missing or renamed.
  2. Normalize type values (map 'C'/'P' to 'call'/'put') before the check.
  3. Update field-name mappings to the current Barchart schema.
  4. Skip rows with incomplete identity instead of failing the entire request.

Example fix

// before
if (!/^(call|put)$/i.test(type) || r.strike === undefined || r.strike === null || r.strike === '' || !expirationValue) throw ...;
// after
const normalizedType = { c: 'call', p: 'put' }[type.toLowerCase()] || type;
if (!/^(call|put)$/i.test(normalizedType) || r.strike == null || r.strike === '' || !expirationValue) throw ...;
Defensive patterns

Strategy: validation

Validate before calling

function rowIdentityOk(r){
  const type = String(r.type||'').trim();
  return /^(call|put|c|p)$/i.test(type) && r.strike != null && r.strike !== '' && !!String(r.expiration||'').trim();
}

Type guard

const hasContractIdentity = (r) => /^(call|put)$/i.test(String(r?.type||'')) && r?.strike != null && !!String(r?.expiration||'').trim();

Try / catch

try {
  const rows = await cli.run(['barchart','greeks', symbol]);
} catch (e) {
  if (e.message.includes('malformed option row identity')) {
    // normalize type/strike/expiration field names, then retry
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/d2db848282ecc5b6. Report an issue: GitHub.

Appendix: source

Thrown at clis/barchart/greeks.js:183

            if (data?.reason === 'exception') {
                throw new CommandExecutionError(`Barchart greeks request failed: ${data.message || 'unknown error'}`);
            }
            throw new CommandExecutionError(`Failed to fetch Barchart greeks for ${symbol}`);
        }
        if (!Array.isArray(data.rows)) {
            throw new CommandExecutionError('Barchart greeks returned an unreadable options payload');
        }
        if (data.rows.length === 0) {
            throw new EmptyResultError('barchart greeks', `No option greeks were returned for ${symbol}. Confirm the symbol, expiration, and Barchart login state.`);
        }
        return data.rows.map(r => {
            if (!r || typeof r !== 'object' || Array.isArray(r)) {
                throw new CommandExecutionError('Barchart greeks returned a malformed option row');
            }
            const type = String(r.type || '').trim();
            const expirationValue = String(r.expiration || '').trim();
            if (!/^(call|put)$/i.test(type) || r.strike === undefined || r.strike === null || r.strike === '' || !expirationValue) {
                throw new CommandExecutionError('Barchart greeks returned a malformed option row identity');
            }
            return {
                type,
                strike: r.strike,
                last: r.last != null ? Number(Number(r.last).toFixed(2)) : null,
                iv: r.iv != null ? Number(Number(r.iv).toFixed(2)) + '%' : null,
                delta: r.delta != null ? Number(Number(r.delta).toFixed(4)) : null,
                gamma: r.gamma != null ? Number(Number(r.gamma).toFixed(4)) : null,
                theta: r.theta != null ? Number(Number(r.theta).toFixed(4)) : null,
                vega: r.vega != null ? Number(Number(r.vega).toFixed(4)) : null,
                rho: r.rho != null ? Number(Number(r.rho).toFixed(4)) : null,
                volume: r.volume,
                openInterest: r.openInterest,
                expiration: expirationValue,
            };
        });
    },
});

View on GitHub (pinned to 49907e53dc)