nautechsystems/nautilus_trader · error · anyhow::Error
Invalid delta: action {action} when size zero, check size_pr
Error message
Invalid delta: action {action} when size zero, check size_precision ({size_precision}) vs data; {data:?} What it means
While parsing a Tardis CSV row into an `OrderBookDelta`, the only legal action for a row with zero size is `Delete` (a level removal). Any other action (Add/Update) with size zero is contradictory — most often the CSV size was misparsed because the configured `size_precision` does not match the data, e.g. a value smaller than 10^-precision truncates to zero. The parser fails fast to avoid emitting a corrupt book delta.
Source
Thrown at crates/adapters/tardis/src/csv/mod.rs:224
) -> anyhow::Result<OrderBookDelta> {
let instrument_id = match instrument_id {
Some(id) => id,
None => parse_instrument_id(&data.exchange, data.symbol),
};
let side = parse_order_side(&data.side);
let price = parse_price(data.price, price_precision);
let size = Quantity::new(data.amount, size_precision);
let order_id = 0; // Not applicable for L2 data
let order = BookOrder::new(side, price, size, order_id);
let action = parse_book_action(data.is_snapshot, size.as_f64());
let flags = 0; // Will be set later if needed
let sequence = 0; // Sequence not available
let ts_event = parse_timestamp(data.timestamp);
let ts_init = parse_timestamp(data.local_timestamp);
anyhow::ensure!(
!(action != BookAction::Delete && size.is_zero()),
"Invalid delta: action {action} when size zero, check size_precision ({size_precision}) vs data; {data:?}"
);
Ok(OrderBookDelta::new(
instrument_id,
action,
order,
flags,
sequence,
ts_event,
ts_init,
))
}
fn parse_quote_record(
data: &TardisQuoteRecord,
price_precision: u8,View on GitHub (pinned to 18893faf8b)
Solutions
- Increase `size_precision` on the instrument definition so the CSV sizes parse to non-zero values (e.g. precision 8 instead of 2).
- Inspect the offending row (`data` is included in the message) and confirm the `size` column against the Tardis dataset spec.
- Re-export or repair the CSV if the size column is genuinely empty/corrupted.
- If your provider intentionally emits zero-size updates, confirm you are using a dataset/action mapping that matches (deletes vs zero-size updates).
Example fix
// before let instrument = define_instrument(size_precision: 2, ...); // after: match precision to the CSV data let instrument = define_instrument(size_precision: 8, ...);
Defensive patterns
Strategy: validation
Validate before calling
def check_size_precision(instrument_precision: int, csv_min_size: str) -> None:
from decimal import Decimal
smallest = Decimal(csv_min_size)
if smallest != 0 and smallest.as_tuple().exponent < -instrument_precision:
raise ValueError(
f"size_precision={instrument_precision} too coarse; CSV has sizes down to {smallest}"
) Try / catch
try:
deltas = load_deltas(path, instrument)
except Exception as e:
if "Invalid delta" in str(e):
# size_precision mismatch: rebuild instrument with finer precision
instrument = rebuild_instrument(size_precision=8)
deltas = load_deltas(path, instrument)
else:
raise Prevention
- Match instrument size_precision to the finest granularity in the Tardis dataset spec
- Pre-scan the CSV for zero-size non-delete rows before full conversion
- Re-derive instrument definitions when switching datasets, never reuse blindly
When it happens
Trigger: Calling `parse_delta_record` (directly or via `load_deltas`, the stream iterator `next`, or `fill_pending_batches`) on a Tardis book CSV row whose parsed size is 0 while the derived action is Add or Update — typically when `size_precision` in the instrument definition is coarser than the actual CSV values.
Common situations: Reusing instrument definitions with a mismatched `size_precision` for a different market; a Tardis dataset change altering size granularity; a truncated or corrupted CSV row where the size column is empty/zero.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Replacement hash {transaction_hash} conflicts with another i
- Included wrap transaction {tx_hash} has invalid block number
- WETH balance overflow for included transaction {tx_hash} at
- {e}
- unrecognized side '{side}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d75cfd49ca1a0cd0.
Report an issue: GitHub.