nautechsystems/nautilus_trader · error · anyhow::Error
Failed to create quantity from fill sz: {e}
Error message
Failed to create quantity from fill sz: {e} What it means
Raised in parse_fill_report when Quantity::from_decimal_dp fails converting fill.sz into a domain Quantity at the instrument's size precision. The code takes fill.sz.abs(), so failure is not from sign but from unrepresentable magnitude, excessive scale, or overflow in the fixed-point QuantityRaw conversion. It indicates the venue-reported fill size can't be represented for this instrument.
Source
Thrown at crates/adapters/hyperliquid/src/http/parse.rs:1188
}
let trade_id = make_fill_trade_id(
&fill.hash,
fill.oid,
fill.px,
fill.sz,
fill.time,
fill.start_position,
);
let order_side = parse_fill_side(&fill.side);
let price_precision = instrument.price_precision();
let size_precision = instrument.size_precision();
let last_px = Price::from_decimal_dp(fill.px, price_precision)
.map_err(|e| anyhow::anyhow!("Failed to create price from fill px: {e}"))?;
let last_qty = Quantity::from_decimal_dp(fill.sz.abs(), size_precision)
.map_err(|e| anyhow::anyhow!("Failed to create quantity from fill sz: {e}"))?;
let fee_amount = fill.fee;
let fee_currency = resolve_fee_currency(fill.fee_token.as_str(), fee_amount, instrument)?;
let commission = Money::from_decimal(fee_amount, fee_currency)
.map_err(|e| anyhow::anyhow!("Failed to create commission from fee: {e}"))?;
// Determine liquidity side based on 'crossed' flag
let liquidity_side = if fill.crossed {
LiquiditySide::Taker
} else {
LiquiditySide::Maker
};
let ts_event = UnixNanos::from(fill.time * 1_000_000);
let report_id = UUID4::new();
let report = FillReport::new(View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the raw fill.sz and the instrument's size_precision; refresh instrument definitions if the venue changed lot size
- Verify the coin-to-instrument mapping so the correct size_precision is applied
- Normalize sz to the instrument precision before conversion or adjust the instrument definition
- Process fills individually so a single unrepresentable fill doesn't discard the entire response
Example fix
// before
let last_qty = Quantity::from_decimal_dp(fill.sz.abs(), size_precision)
.map_err(|e| anyhow::anyhow!("Failed to create quantity from fill sz: {e}"))?;
// after
let last_qty = Quantity::from_decimal_dp(fill.sz.abs(), size_precision)
.map_err(|e| anyhow::anyhow!("Failed to create quantity from fill sz {}: {e}", fill.sz))?; Defensive patterns
Strategy: try-catch
Validate before calling
# Python: check fill size against instrument size precision assert fill_sz > 0, "fill size must be positive"
Try / catch
try:
fills = client.request_fill_reports(...)
except ValueError as e:
if "fill sz" in str(e):
log.warning("skipping fill with unrepresentable size: %s", e)
else:
raise Prevention
- Keep instrument size_precision synchronized with venue lot-size changes
- Watch for fills near fixed-point limits on high-value assets
- Process fills individually with per-item error handling
When it happens
Trigger: Calling fill_reports_from_response for a fill whose sz has more decimal places than the instrument's size_precision, or whose scaled value exceeds QuantityRaw's range.
Common situations: Assets whose size decimals changed since instruments were loaded; extremely large fills near fixed-point limits; malformed/precision-heavy sz values from the venue API.
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
- Failed to create quantity from filled_sz: {e}
- Failed to create price from fill px: {e}
- Failed to create commission from fee: {e}
- Skipping non-trade execution: {:?}
- Skipping execution without side: {:?}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/161b1b8d6d51ade3.
Report an issue: GitHub.