nautechsystems/nautilus_trader · error

Chart data status is '{}', expected 'ok'

Error message

Chart data status is '{}', expected 'ok'

What it means

parse_bars validates that the Deribit tradingview chart_data response reports status 'ok' before converting ticks into bars. Any other status (e.g. 'error', 'no_data') means the tick data is unusable, so parsing fails.

Source

Thrown at crates/adapters/deribit/src/common/parse.rs:868

/// instead of `chart_data.volume` (base currency) - see [`use_cost_for_bar_volume`].
///
/// # Errors
///
/// Returns an error if:
/// - The status is not "ok"
/// - Array lengths are inconsistent
/// - No data points are present
pub fn parse_bars(
    chart_data: &DeribitTradingViewChartData,
    bar_type: BarType,
    price_precision: u8,
    size_precision: u8,
    use_cost_for_volume: bool,
    ts_init: UnixNanos,
) -> anyhow::Result<Vec<Bar>> {
    // Check status
    if chart_data.status != "ok" {
        anyhow::bail!(
            "Chart data status is '{}', expected 'ok'",
            chart_data.status
        );
    }

    let num_bars = chart_data.ticks.len();

    // Verify array lengths match
    anyhow::ensure!(
        chart_data.open.len() == num_bars
            && chart_data.high.len() == num_bars
            && chart_data.low.len() == num_bars
            && chart_data.close.len() == num_bars
            && chart_data.volume.len() == num_bars
            && chart_data.cost.len() == num_bars,
        "Inconsistent array lengths in chart data"
    );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Validate instrument_name and the start/end timestamps of the bar request
  2. Check response status before calling parse_bars and surface a clearer error
  3. Handle 'no_data' style statuses gracefully for instruments with no history
  4. Check for Deribit rate limits or API errors in the request path

Example fix

// before
let bars = parse_bars(&chart_data, ...)?; // may fail on status
// after
if chart_data.status != "ok" {
    log::warn!("Chart data unavailable: status={}", chart_data.status);
    return Ok(Vec::new());
}
let bars = parse_bars(&chart_data, ...)?;
Defensive patterns

Strategy: validation

Validate before calling

if chart_data.status != "ok" {
    log::warn!("chart status={}, skipping parse", chart_data.status);
    return Ok(Vec::new());
}

Type guard

fn chart_ok(c: &GetChartTradesResponse) -> bool { c.status == "ok" }

Try / catch

match parse_bars(&chart_data, ...).await /* or sync */ {
    Err(e) if e.to_string().contains("expected 'ok'") => {
        warn!("chart data unavailable: {}", chart_data.status);
        return Ok(Vec::new());
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling parse_bars with a GetChartTradesResponse whose status != "ok" — Deribit rejected the chart request or returned no valid data.

Common situations: Requesting chart data for an invalid/unknown instrument_name or out-of-range time window, Deribit rate limiting, instrument without trading history.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/e3dbc620801375d3. Report an issue: GitHub.