nautechsystems/nautilus_trader · critical

Error: No ask orders for best ask size

Error message

Error: No ask orders for best ask size

What it means

This panic fires in the FFI wrapper `orderbook_best_ask_size` when `OrderBook::best_ask_size()` returns None because no ask orders exist in the book. Under `abort_on_panic` the panic aborts the entire process rather than surfacing an error to the caller.

Source

Thrown at crates/model/src/ffi/orderbook/book.rs:297

/// Panics if there are no bid orders for best bid size.
#[unsafe(no_mangle)]
#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
pub extern "C" fn orderbook_best_bid_size(book: &mut OrderBook) -> Quantity {
    abort_on_panic(|| {
        book.best_bid_size()
            .expect("Error: No bid orders for best bid size")
    })
}

/// # Panics
///
/// Panics if there are no ask orders for best ask size.
#[unsafe(no_mangle)]
#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
pub extern "C" fn orderbook_best_ask_size(book: &mut OrderBook) -> Quantity {
    abort_on_panic(|| {
        book.best_ask_size()
            .expect("Error: No ask orders for best ask size")
    })
}

/// # Panics
///
/// Panics if unable to calculate spread (requires at least one bid and one ask).
#[unsafe(no_mangle)]
pub extern "C" fn orderbook_spread(book: &mut OrderBook) -> f64 {
    abort_on_panic(|| {
        book.spread()
            .expect("Error: Unable to calculate `spread` (no bid or ask)")
    })
}

/// # Panics
///
/// Panics if unable to calculate midpoint (requires at least one bid and one ask).
#[unsafe(no_mangle)]

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the ask side is non-empty before calling the FFI function.
  2. Populate the book with quotes/depth containing ask sizes before querying.
  3. Handle the empty case caller-side by returning None/skipping the computation.
  4. Check feed connectivity and that ask-side volume updates are subscribed.

Example fix

// before (Python FFI caller)
ask_size = orderbook_best_ask_size(book)
// after
if has_ask_orders(book):
    ask_size = orderbook_best_ask_size(book)
else:
    ask_size = None
Defensive patterns

Strategy: validation

Validate before calling

def can_get_best_ask_size(book) -> bool:
    return book.has_orders() and book.asks_len() > 0

Prevention

When it happens

Trigger: Calling `orderbook_best_ask_size(book)` on a book with an empty ask side or with ask levels that carry no size data.

Common situations: Ask size missing from the market-data feed; querying a freshly created or cleared book; trade-only or bid-only data streams; illiquid symbols with no resting asks.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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