nautechsystems/nautilus_trader · error
Invalid zero size for {action}
Error message
Invalid zero size for {action} What it means
When parsing a Tardis order book level, only a Delete action may carry a zero size. Any other action (Add/Update) with size == 0 is considered corrupt input, so parse_book_level rejects it via anyhow::ensure! before constructing the OrderBookDelta.
Source
Thrown at crates/adapters/tardis/src/machine/parse.rs:493
level: &BookLevel,
is_snapshot: bool,
ts_event: UnixNanos,
ts_init: UnixNanos,
) -> anyhow::Result<OrderBookDelta> {
let amount = normalize_amount(level.amount, size_precision);
let action = parse_book_action(is_snapshot, amount);
let price = Price::new(level.price, price_precision);
let size = Quantity::new(amount, size_precision);
let order_id = 0; // Not applicable for L2 data
let order = BookOrder::new(side, price, size, order_id);
let flags = if is_snapshot {
RecordFlag::F_SNAPSHOT as u8
} else {
0
};
let sequence = 0; // Not available
anyhow::ensure!(
!(action != BookAction::Delete && size.is_zero()),
"Invalid zero size for {action}"
);
Ok(OrderBookDelta::new(
instrument_id,
action,
order,
flags,
sequence,
ts_event,
ts_init,
))
}
/// Parse a book snapshot message into a quote tick, returning an error on invalid data.
/// Parse a book snapshot message into a quote tick.
///View on GitHub (pinned to 18893faf8b)
Solutions
- Pre-filter Tardis book records where action != 'delete' and size == 0 before feeding the machine parser.
- Treat such records as deletes if that matches the venue semantics (set action to delete instead of add/update).
- Re-download the affected Tardis data range; the record may be corrupt in the source capture.
- If legitimate for a venue, update the adapter's normalization (map zero-size non-delete to Delete) upstream of this check.
Example fix
// before
anyhow::ensure!(!(action != BookAction::Delete && size.is_zero()), "Invalid zero size for {action}");
// after
let action = if action != BookAction::Delete && size.is_zero() {
tracing::debug!("Coercing zero-size {action} to Delete");
BookAction::Delete
} else {
action
}; Defensive patterns
Strategy: validation
Validate before calling
// filter Tardis book levels before parsing levels.retain(|lvl| lvl.action == "delete" || lvl.size > 0);
Type guard
fn is_valid_level(lvl: &BookLevel) -> bool { lvl.action == BookAction::Delete || !lvl.size.is_zero() } Prevention
- Sanitize Tardis captures (drop or coerce zero-size non-delete records) before feeding the machine.
- Re-download data ranges that trigger parse failures — they are often corrupt at source.
- Log skipped records to spot venue-specific anomalies early.
When it happens
Trigger: parse_book_msg_as_deltas -> parse_book_level receiving a Tardis book record with action != 'delete' and size == 0 (or PriceSize parsed from a record whose size field is 0/null).
Common situations: Corrupt or non-conformant Tardis data files; venue-specific anomalies in recorded L2/L3 streams; a Tardis schema change emitting zero-size updates for non-delete actions.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid depth {depth} for Binance Futures order book. Valid
- invalid depth {depth}; supported depths: {DERIBIT_BOOK_VALID
- market-book size must be non-negative
- {e}
- `handle_book_mbo` {IMPL_ERR} `{}`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/113a7bda60c35aea.
Report an issue: GitHub.