nautechsystems/nautilus_trader · error
Generic spread contract count overflowed for {symbol}
Error message
Generic spread contract count overflowed for {symbol} What it means
While summing generic spread leg ratios into an i64 contract count, `spread_contract_count` uses `checked_add` and raises this error if the running total overflows. It protects against absurdly large or corrupt spread symbols producing an invalid commission.
Source
Thrown at crates/execution/src/models/fee.rs:357
.and_then(|v| mul_checked(v, contracts))?;
Money::from_decimal(total, self.commission.currency).map_err(Into::into)
}
}
fn spread_contract_count(instrument: &InstrumentAny) -> anyhow::Result<Decimal> {
let instrument_id = instrument.id();
let symbol = instrument_id.symbol.as_str();
if !instrument.is_spread() || !symbol.contains(GENERIC_SPREAD_ID_SEPARATOR) {
return Ok(Decimal::ONE);
}
let mut total = 0_i64;
for component in symbol.split(GENERIC_SPREAD_ID_SEPARATOR) {
let ratio = spread_leg_ratio(component)
.ok_or_else(|| anyhow::anyhow!("Invalid generic spread leg component: {component}"))?;
total = total.checked_add(ratio).ok_or_else(|| {
anyhow::anyhow!("Generic spread contract count overflowed for {symbol}")
})?;
}
Ok(total.into())
}
fn spread_leg_ratio(component: &str) -> Option<i64> {
if let Some(rest) = component.strip_prefix("((") {
let (ratio, symbol) = rest.split_once("))")?;
return spread_leg_ratio_parts(ratio, symbol);
}
let rest = component.strip_prefix('(')?;
let (ratio, symbol) = rest.split_once(')')?;
spread_leg_ratio_parts(ratio, symbol)
}
fn spread_leg_ratio_parts(ratio: &str, symbol: &str) -> Option<i64> {View on GitHub (pinned to 18893faf8b)
Solutions
- Validate the instrument symbol and its leg ratios come from a trusted source before fee computation.
- Cap or sanity-check leg ratios when constructing generic spread instruments.
- Investigate the symbol string reported in the message for corruption.
Defensive patterns
Strategy: validation
Validate before calling
ratios = [spread_leg_ratio(c) for c in symbol.split(SEP)] assert all(r is not None and 0 < r < 10**6 for r in ratios), "implausible leg ratios"
Try / catch
let count = spread_contract_count(symbol).unwrap_or_else(|e| {
log::error!("overflow for {symbol}: {e}"); Decimal::ONE
}); Prevention
- Bound leg ratio magnitudes when building generic spread instruments.
- Treat huge ratio sums as corrupt data and reject the instrument early.
When it happens
Trigger: Calling `get_commission` on a generic spread symbol whose leg ratios sum beyond i64::MAX — practically only possible with pathological/corrupt symbol components carrying huge ratios.
Common situations: Corrupted or adversarially crafted instrument IDs; parsing symbols with extremely large numeric leg components.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- commission calculation overflow
- Invalid generic spread leg component: {component}
- WETH balance overflow for included transaction {tx_hash} at
- DurationNanos overflow in from_micros
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/369c891ede16e025.
Report an issue: GitHub.