nautechsystems/nautilus_trader · error · anyhow::Error
slippage_bps parameter {value} exceeds the u32 range
Error message
slippage_bps parameter {value} exceeds the u32 range What it means
The SubmitOrder command's params carried a 'slippage_bps' key read as u64, and its value did not fit in u32 (max 4,294,967,295). The per-order override is converted with u32::try_from before being compared against max_slippage_bps, so oversized values are rejected before quoting. In practice the value is a unit mistake rather than a deliberate 42-million-bps slippage request.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1218
quote_token.address
);
}
let amount_in = quantity_to_raw_amount(order.quantity(), base_token.decimals)?;
if amount_in > U256::from(self.transaction_limits.max_order_amount) {
anyhow::bail!(
"Order amount {amount_in} exceeds the configured `max_order_amount` {}",
self.transaction_limits.max_order_amount
);
}
let slippage_bps = match cmd
.params
.as_ref()
.and_then(|params| params.get_u64("slippage_bps"))
{
Some(value) => u32::try_from(value).map_err(|_| {
anyhow::anyhow!("slippage_bps parameter {value} exceeds the u32 range")
})?,
None => self.transaction_limits.slippage_bps,
};
if slippage_bps > self.transaction_limits.max_slippage_bps {
anyhow::bail!(
"Slippage {slippage_bps} bps exceeds the configured `max_slippage_bps` {}",
self.transaction_limits.max_slippage_bps
);
}
let profiler = self
.core
.cache()
.pool_profiler(&instrument_id)
.cloned()
.ok_or_else(|| {
anyhow::anyhow!(View on GitHub (pinned to 2114cf6f76)
Solutions
- Send slippage in basis points as a small integer: 50 = 0.50%, 200 = 2%
- Ensure the value fits u32 and is at or below the configured transaction_limits.max_slippage_bps (which itself must be < 10000)
- If you did not intend an override, omit 'slippage_bps' entirely and let the default slippage_bps limit apply
Example fix
# before
order = self.order_factory.market(
instrument_id,
order_side=OrderSide.SELL,
quantity=base_qty,
params={'slippage_bps': 5_000_000_000}, # exceeds u32
)
# after: 0.50% slippage in basis points
order = self.order_factory.market(
instrument_id,
order_side=OrderSide.SELL,
quantity=base_qty,
params={'slippage_bps': 50},
) Defensive patterns
Strategy: validation
Validate before calling
def sanitized_slippage_bps(params: dict | None, max_allowed: int) -> int | None:
"""Return a safe per-order slippage override, or None to use the default."""
if not params or 'slippage_bps' not in params:
return None
value = params['slippage_bps']
assert isinstance(value, int) and 0 <= value <= 0xFFFFFFFF, 'slippage_bps must fit u32'
assert value <= max_allowed, f'slippage_bps above max_slippage_bps={max_allowed}'
return value Type guard
def valid_slippage_param(params: dict | None) -> bool:
v = (params or {}).get('slippage_bps')
return v is None or (isinstance(v, int) and not isinstance(v, bool) and 0 <= v <= 0xFFFFFFFF) Prevention
- Express slippage as small bps integers (50 = 0.50%); never pass raw scaled fractions
- Centralize order-params construction in one helper that clamps slippage to the configured max_slippage_bps
When it happens
Trigger: submit_order with params like {'slippage_bps': 50_000_000_000} — e.g. slippage passed in wei-style raw units, in hundredths of a bip, or a percentage multiplied by the wrong scale.
Common situations: Strategy code computing slippage from a Decimal price and forgetting to cast through a bounded integer; passing 1/1e9-style fractions scaled into a u64; config templates using different bps conventions between teams.
Related errors
- `slippage_bps` {slippage_bps} exceeds `max_slippage_bps` {ma
- Slippage {slippage_bps} bps must be below {BPS_DENOMINATOR}
- Pool {instrument_id} fee {fee} exceeds uint24
- Minimum output derivation overflow
- height must be positive, was {self.height}
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/e1b4f5b56f1ed232.
Report an issue: GitHub.