nautechsystems/nautilus_trader · critical
Error: No bid orders for best bid size
Error message
Error: No bid orders for best bid size
What it means
This panic occurs in the FFI wrapper `orderbook_best_bid_size` when `OrderBook::best_bid_size()` returns None because there are no bid orders at the best bid level (or anywhere on the bid side). The `abort_on_panic` wrapper makes this a process abort, not a catchable FFI error.
Source
Thrown at crates/model/src/ffi/orderbook/book.rs:285
/// Panics if there are no ask orders for best ask price.
#[unsafe(no_mangle)]
#[cfg_attr(feature = "high-precision", allow(improper_ctypes_definitions))]
pub extern "C" fn orderbook_best_ask_price(book: &mut OrderBook) -> Price {
abort_on_panic(|| {
book.best_ask_price()
.expect("Error: No ask orders for best ask price")
})
}
/// # Panics
///
/// 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).View on GitHub (pinned to 18893faf8b)
Solutions
- Check the book has bid orders (non-empty bids / has_orders) before calling the FFI getter.
- Feed the book quote or depth data that includes bid sizes before querying sizes.
- Return None from caller-side logic when the book has no bids instead of calling the panicking FFI function.
- Validate data feed configuration so bid volume is present for the instrument.
Example fix
// before (Python FFI caller)
bid_size = orderbook_best_bid_size(book)
// after
if has_bid_orders(book):
bid_size = orderbook_best_bid_size(book)
else:
bid_size = None Defensive patterns
Strategy: validation
Validate before calling
def can_get_best_bid_size(book) -> bool:
return book.has_orders() and book.bids_len() > 0 Prevention
- Confirm the data feed includes bid volume, not price-only levels
- Gate size queries on a book-initialized flag
- Treat empty books as an expected state and query optional accessors instead of FFI panicking ones
- Remember FFI panics abort the process — they cannot be caught as exceptions
When it happens
Trigger: Calling `orderbook_best_bid_size(book)` when the bid side is empty or size information has not been populated (e.g. price-only book updates without volume).
Common situations: Books built from data sources lacking bid size; querying immediately after a clear/reset; L1 feed gaps where the bid row vanished; calling before the first quote arrives.
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
- Error: No bid orders for best bid price
- Error: No ask orders for best ask price
- Error: No ask orders for best ask size
- Error: Unable to calculate `spread` (no bid or ask)
- Error: Unable to calculate `midpoint` (no bid or ask)
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e95228a9af8e440b.
Report an issue: GitHub.