jackwener/OpenCLI · error · CommandExecutionError

Barchart greeks returned an unreadable options payload

Error message

Barchart greeks returned an unreadable options payload

What it means

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.

Source

Thrown at clis/barchart/greeks.js:171

        } catch(e) {
          return { ok: false, reason: 'exception', message: e?.message || String(e) };
        }
      })()
    `));
        if (!data || data.ok !== true) {
            if (data?.reason === 'http') {
                throw new CommandExecutionError(`Barchart greeks request failed: HTTP ${data.status}${data.statusText ? ` ${data.statusText}` : ''}`);
            }
            if (data?.reason === 'malformed') {
                throw new CommandExecutionError(`Barchart greeks returned an unreadable options payload${data.message ? `: ${data.message}` : ''}`);
            }
            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,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-authenticate with Barchart (refresh login state/cookies) and retry the command.
  2. Log the raw response body to inspect what Barchart actually returned.
  3. Verify the symbol actually has listed options (e.g. SPY vs a delisted ticker).
  4. Update the CLI/library in case Barchart changed its payload schema.

Example fix

// before
const data = JSON.parse(body);
if (!Array.isArray(data.rows)) throw ...;
// after
const data = typeof body === 'string' && body.trim().startsWith('<') ? null : JSON.parse(body);
if (!data || !Array.isArray(data.rows)) throw new CommandExecutionError('Barchart greeks returned an unreadable options payload');
Defensive patterns

Strategy: type-guard

Validate before calling

function hasGreeksPayload(d){ return d && typeof d === 'object' && Array.isArray(d.rows); }
// run after fetching, before calling the CLI mapper

Type guard

const isGreeksPayload = (d) => !!d && typeof d === 'object' && !Array.isArray(d) && Array.isArray(d.rows);

Try / catch

try {
  const rows = await cli.run(['barchart','greeks', symbol]);
} catch (e) {
  if (e.message.includes('unreadable options payload')) {
    // inspect raw response / re-authenticate with Barchart
  }
}

Prevention

When it happens

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

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

Related errors


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