nautechsystems/nautilus_trader · error · anyhow::Error
Swap quote failed for {instrument_id}: {e}
Error message
Swap quote failed for {instrument_id}: {e} What it means
The local pool profiler's swap_exact_in(amount_in, zero_for_one, None) simulation returned an error while trying to quote the exact-input swap. The underlying cause is appended ({e}) and typically comes from the tick-walk math: not enough (or no) liquidity in the direction being traded to consume amount_in within the simulated range, or other arithmetic infeasibility in the local pool state.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1255
"No pool profiler for {instrument_id}; an active data subscription is required to quote the swap"
)
})?;
if !profiler.is_initialized {
anyhow::bail!("Pool profiler for {instrument_id} is not initialized");
}
let profiler_block = profiler
.last_processed_event
.as_ref()
.map(|position| position.number)
.ok_or_else(|| {
anyhow::anyhow!("Pool profiler for {instrument_id} has processed no events")
})?;
let zero_for_one = base_token.address == pool.token0.address;
let quote = profiler
.swap_exact_in(amount_in, zero_for_one, None)
.map_err(|e| anyhow::anyhow!("Swap quote failed for {instrument_id}: {e}"))?;
let amount_filled = if zero_for_one {
quote.amount0
} else {
quote.amount1
};
if amount_filled != I256::from(amount_in) {
anyhow::bail!(
"Local quote for {instrument_id} filled {amount_filled} of the {amount_in} order amount; pool liquidity cannot fill the order"
);
}
let quoted_amount_out = exact_output_amount("e, zero_for_one)?;
let min_amount_out = derive_min_amount_out(quoted_amount_out, slippage_bps)?;
self.ensure_transaction_ready(TransactionPurpose::Swap)?;
View on GitHub (pinned to 2114cf6f76)
Solutions
- Reduce the order size and retry; the separate 'filled' check shows how much the pool could actually absorb
- Check the pool's current liquidity and tick range on-chain (or via the data feed) to size orders within available depth
- Confirm the profiler is current (recent events processed) before concluding liquidity is genuinely insufficient
- Route around dead pools: de-list instruments whose profiler repeatedly fails to quote
Example fix
# before: order sized far above pool depth qty = Quantity.from_raw(instrument_id, 10**24) self.submit_order(market_order(instrument_id, qty)) # Swap quote failed # after: size within a fraction of observed fill capacity last_fill_raw = self._observed_max_fill_raw # tracked from quotes/deltas qty = Quantity.from_raw(instrument_id, min(10**24, last_fill_raw // 4)) self.submit_order(market_order(instrument_id, qty))
Defensive patterns
Strategy: validation
Validate before calling
# Size orders within observed pool depth before submitting
last_quote = self.cache.quote_tick(instrument_id)
assert last_quote is not None, 'no quote yet'
max_raw = int(self._max_observed_fill_raw * 0.25) # quarter of observed absorption
assert int(order_qty_raw) <= max_raw, f'{instrument_id}: size exceeds local depth estimate' Try / catch
try:
self.submit_order(order)
except Exception as e:
if 'Swap quote failed' in str(e):
self._max_observed_fill_raw //= 2 # back off size and retry next signal
return
raise Prevention
- Track recent fill capacity from quotes/deltas and cap order size to a fraction of it
- Skip instruments whose local quote repeatedly fails; treat it as a no-liquidity signal, not a transient error
When it happens
Trigger: submit_order whose amount_in exceeds what the profiler's reconstructed liquidity can absorb in zero_for_one (or the reverse) direction; quoting against a stale/partial pool state after large liquidity removals; amount_in so large the tick walk runs out of initialized ticks.
Common situations: Thin single-sided liquidity pools; trading right after an LP burned most liquidity; order sizing derived from a different venue's depth; profiler state lagging recent Swap/Burn events.
Related errors
- Pool {instrument_id} has no fee tier
- Pool {instrument_id} fee {fee} exceeds uint24
- No pool profiler for {instrument_id}; an active data subscri
- Pool profiler for {instrument_id} has processed no events
- Finalized transaction {} emitted {} Swap logs; expected exac
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/4858adcc28c534f3.
Report an issue: GitHub.