nautechsystems/nautilus_trader · error · anyhow::Error

options chain buffer capacity overflow

Error message

options chain buffer capacity overflow

What it means

The options-chain streaming iterator allocates an internal buffer of `chunk_size * 2` records. On platforms where `usize` is small (or with an absurdly large `chunk_size`), the multiplication can overflow; rather than wrap silently, `options_chain_buffer_capacity` uses `checked_mul` and fails with this error.

Source

Thrown at crates/adapters/tardis/src/csv/stream.rs:57

        parse_options_chain_record_as_quote, parse_quote_record, parse_trade_record,
        record::{
            TardisBookUpdateRecord, TardisOptionsChainRecord, TardisOrderBookSnapshot5Record,
            TardisOrderBookSnapshot25Record, TardisQuoteRecord, TardisTradeRecord,
        },
    },
};

const MAX_STREAM_CHUNK_SIZE: usize = 1_000_000;

fn validate_stream_chunk_size(chunk_size: usize) -> anyhow::Result<()> {
    check_in_range_inclusive_usize(chunk_size, 1, MAX_STREAM_CHUNK_SIZE, stringify!(chunk_size))?;
    Ok(())
}

fn options_chain_buffer_capacity(chunk_size: usize) -> anyhow::Result<usize> {
    chunk_size
        .checked_mul(2)
        .ok_or_else(|| anyhow::anyhow!("options chain buffer capacity overflow"))
}

////////////////////////////////////////////////////////////////////////////////
// OrderBookDelta Streaming
////////////////////////////////////////////////////////////////////////////////

/// Streaming iterator over CSV records that yields chunks of parsed data.
struct DeltaStreamIterator {
    reader: Reader<Box<dyn std::io::Read>>,
    record: StringRecord,
    buffer: Vec<OrderBookDelta>,
    chunk_size: usize,
    instrument_id: Option<InstrumentId>,
    price_precision: u8,
    size_precision: u8,
    last_ts_init: Option<UnixNanos>,
    last_is_snapshot: bool,
    limit: Option<usize>,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a realistic `chunk_size` (e.g. thousands of records, well within `usize::MAX / 2`).
  2. Clamp or validate the configured chunk size before constructing the stream.
  3. Check where the chunk size is computed; an overflowing upstream calculation is likely the root cause.

Example fix

// before
let stream = OptionsChainStream::new(usize::MAX, ...);
// after
let chunk_size = requested_chunk_size.min(1_000_000);
let stream = OptionsChainStream::new(chunk_size, ...);
Defensive patterns

Strategy: validation

Validate before calling

def validate_chunk_size(chunk_size: int) -> int:
    max_safe = (1 << 63) // 2  # conservative usize/2 bound
    if not (0 < chunk_size < max_safe):
        raise ValueError(f"chunk_size must be in (0, {max_safe}), got {chunk_size}")
    return chunk_size

Type guard

def is_safe_chunk_size(n: int) -> bool:
    return isinstance(n, int) and 0 < n < (1 << 62)

Prevention

When it happens

Trigger: Calling the options-chain stream constructor (`new`) with a `chunk_size` so large that `chunk_size * 2` exceeds `usize::MAX` (practically only on 16-bit `usize` or with adversarial/huge values on 32-bit).

Common situations: Programmatic/derived chunk sizes (e.g. `usize::MAX` or a computed value from config) rather than realistic record counts; running on an unusual embedded target.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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