nautechsystems/nautilus_trader · error · anyhow::Error
Cannot quote swap with zero amount
Error message
Cannot quote swap with zero amount
What it means
PoolProfiler::quote_swap simulates a Uniswap-v3-style swap; it rejects a zero amount_specified up front because a zero-amount swap has no defined path or resulting price. The pool must also be initialized (check_if_initialized) before quoting. Callers like swap_exact_in/swap_exact_out and sqrt-price traversal helpers all funnel through this guard.
Source
Thrown at crates/model/src/defi/pool_analysis/profiler.rs:749
/// - Fee breakdown (LP fees and protocol fees)
/// - List of crossed ticks with state snapshots
///
/// # Errors
///
/// Returns error if:
/// - Pool fee is not configured
/// - Fee growth arithmetic overflows when scaling by liquidity
/// - Swap step calculations fail
pub fn quote_swap(
&self,
amount_specified: I256,
zero_for_one: bool,
sqrt_price_limit_x96: Option<U160>,
) -> anyhow::Result<SwapQuote> {
self.check_if_initialized(PoolEventKind::Swap)?;
if amount_specified.is_zero() {
anyhow::bail!("Cannot quote swap with zero amount");
}
if let Some(price_limit) = sqrt_price_limit_x96 {
self.validate_price_limit(price_limit, zero_for_one)?;
}
let limit = sqrt_price_limit_x96.unwrap_or_else(|| {
if zero_for_one {
MIN_SQRT_RATIO + U160::from(1)
} else {
MAX_SQRT_RATIO - U160::from(1)
}
});
self.simulate_swap_through_ticks(amount_specified, zero_for_one, limit, false)
}
/// Simulates an exact input swap (know input amount, calculate output amount).View on GitHub (pinned to 18893faf8b)
Solutions
- Skip zero-amount quotes: check amount_specified.is_zero() before calling and return a neutral/default quote instead
- Clamp or filter upstream so amounts fed into quote_swap are strictly positive
- Ensure the profiler is initialized for the pool before quoting (check_if_initialized passes)
- Review the caller producing the amount — a zero usually indicates a missing or mis-decoded input
Example fix
// before
let quote = profiler.quote_swap(amount, zero_for_one, None)?;
// after
if amount.is_zero() {
return Ok(None); // nothing to quote
}
let quote = profiler.quote_swap(amount, zero_for_one, None)?; Defensive patterns
Strategy: validation
Validate before calling
if amount_specified.is_zero() {
return Ok(None); // nothing to quote
}
if !profiler.is_initialized(PoolEventKind::Swap) {
return Ok(None);
} Type guard
fn quotable(profiler: &PoolProfiler, amount: U256) -> bool {
!amount.is_zero() && profiler.is_initialized(PoolEventKind::Swap)
} Try / catch
match profiler.quote_swap(amount, zero_for_one, limit) {
Ok(q) => Some(q),
Err(e) if e.to_string().contains("zero amount") => None,
Err(e) => return Err(e),
} Prevention
- Skip zero-amount deltas before simulating swaps
- Initialize the profiler from a swap/liquidity snapshot before quoting
- Clamp user- or data-supplied amounts to a positive minimum
- Log skipped zero-amount quotes for data-quality review
When it happens
Trigger: Calling quote_swap (directly or via swap_exact_in/swap_exact_out/swap_to_lower_sqrt_price/swap_to_higher_sqrt_price) with amount_specified == 0, or quoting on a pool profiler that was never initialized with a swap/liquidity snapshot.
Common situations: Computers replaying pools with no trade volume passing zero amounts; a loop that processes empty deltas; building quotes from user input where 0 wasn't validated; uninitialized profiler used before mint events loaded.
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
- Cannot calculate execution price with zero amounts
- Price limit must be less than current price for zero_for_one
- Price limit must be greater than current price for one_for_z
- No liquidity
- Position liquidity {} is less than the requested burn amount
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0234c440b51e788f.
Report an issue: GitHub.