nautechsystems/nautilus_trader · warning
Executed amount {amount} is below representable quantity pre
Error message
Executed amount {amount} is below representable quantity precision {FIXED_PRECISION} What it means
After scaling the raw U256 amount into a Quantity, the adapter checks the result is nonzero. If the raw amount is smaller than one unit of the representable fixed-point precision (FIXED_PRECISION), the quantity truncates to zero and the adapter bails rather than propagate a zero executed quantity.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:5263
Price::from_decimal_dp(quote.as_decimal() / last_qty.as_decimal(), FIXED_PRECISION)
.map_err(anyhow::Error::from)
}
fn raw_amount_to_quantity(amount: U256, decimals: u8) -> anyhow::Result<Quantity> {
if amount.is_zero() {
anyhow::bail!("Executed amount must be positive");
}
let quantity = if decimals >= FIXED_PRECISION {
let scale = U256::from(10u64)
.checked_pow(U256::from(decimals - FIXED_PRECISION))
.ok_or_else(|| anyhow::anyhow!("Executed amount scaling overflow"))?;
Quantity::from_u256(amount / scale, FIXED_PRECISION).map_err(anyhow::Error::from)?
} else {
Quantity::from_u256(amount, decimals).map_err(anyhow::Error::from)?
};
if quantity.is_zero() {
anyhow::bail!(
"Executed amount {amount} is below representable quantity precision {FIXED_PRECISION}"
);
}
Ok(quantity)
}
fn exact_output_amount(quote: &SwapQuote, zero_for_one: bool) -> anyhow::Result<U256> {
let amount = if zero_for_one {
quote.amount1
} else {
quote.amount0
};
if !amount.is_negative() {
anyhow::bail!("Swap quote output amount {amount} is not a positive output");
}
Ok(amount.unsigned_abs())
}View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the token decimals configured match the actual on-chain token
- Treat the execution as dust: skip it rather than erroring, or accumulate amounts before converting
- If the fill is real and important, check for a decimals/parsing bug upstream
Example fix
// before
let qty = raw_amount_to_quantity(amount, decimals)?;
// after
if amount < U256::from(10u64).pow(decimals.into()) {
tracing::warn!("dust execution {} below precision, skipping", amount);
return Ok(None);
}
let qty = raw_amount_to_quantity(amount, decimals)?; Defensive patterns
Strategy: validation
Validate before calling
let scale = U256::from(10u64).pow(U256::from(decimals));
if amount < scale {
tracing::warn!("amount {amount} below 1 unit at {decimals} decimals; treating as dust");
return Ok(None);
} Try / catch
match raw_amount_to_quantity(amount, decimals) {
Ok(q) => handle(q),
Err(e) if e.to_string().contains("below representable") => handle_dust(amount),
Err(e) => return Err(e),
} Prevention
- Confirm token decimals from the token contract, not hardcoded values
- Handle dust explicitly (skip or batch) instead of letting it error
When it happens
Trigger: raw_amount_to_quantity receives a tiny raw amount (e.g. 1..scale-1 wei) with token decimals >= FIXED_PRECISION, so amount/scale rounds to zero.
Common situations: Dust fills/swaps on high-decimals tokens; token decimals misconfigured so scale is much larger than expected.
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
- {type_name} raw value {raw} exceeds {raw_max_name}={raw_max}
- Instrument not found in cache: {symbol}
- Failed to load active execution intent: {e}
- Failed to start replacement transaction persistence: {e}
- Failed to lock active execution intent {intent_id}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d2e6e106e6e96374.
Report an issue: GitHub.