nautechsystems/nautilus_trader · error
No `quote_spend_limits` entry for BUY token pair {token_in}
Error message
No `quote_spend_limits` entry for BUY token pair {token_in} -> {token_out} What it means
BUY swaps spend the quote token, and the adapter enforces a per-pair quote-spend ceiling. `transaction_limits.quote_spend_limits` has no entry for the (token_in, token_out) pair, so a BUY order cannot be cost-capped and is rejected.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1631
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 quote_spend_ceiling = if order.order_side() == OrderSide::Buy {
let ceiling = self
.transaction_limits
.quote_spend_limits
.get(&(token_in, token_out))
.ok_or_else(|| {
anyhow::anyhow!(
"No `quote_spend_limits` entry for BUY token pair {token_in} -> {token_out}"
)
})?;
anyhow::ensure!(
ceiling.spend_token == quote_token.address,
"Quote spend limit for {token_in} -> {token_out} is denominated in {}, expected quote token {}",
ceiling.spend_token,
quote_token.address
);
anyhow::ensure!(
ceiling.spend_token_decimals == quote_token.decimals,
"Quote spend limit for token {} uses {} decimals, expected pool quote-token decimals {}",
ceiling.spend_token,
ceiling.spend_token_decimals,
quote_token.decimals
);
Some(ceiling)
} else {View on GitHub (pinned to 18893faf8b)
Solutions
- Add a `quote_spend_limits` entry keyed by the exact (token_in, token_out) pair used by the order
- Verify the token addresses in the map match the pool's token addresses exactly (same checksum/case)
- Either configure limits for all BUY pairs you trade, or route the order as a SELL-side pair if appropriate
Example fix
// before
quote_spend_limits: {}
// after
quote_spend_limits: {
(usdc_addr, weth_addr): QuoteSpendCeiling { spend_token: usdc_addr, spend_token_decimals: 6, max_spend: ... },
} Defensive patterns
Strategy: validation
Validate before calling
if order.order_side() == OrderSide::Buy
&& !transaction_limits.quote_spend_limits.contains_key(&(token_in, token_out)) {
return Err(format!("add quote_spend_limits entry for {token_in} -> {token_out}"));
} Type guard
fn has_spend_limit(limits: &HashMap<(Address, Address), Ceiling>, tin: Address, tout: Address) -> bool {
limits.contains_key(&(tin, tout))
} Try / catch
match client.submit_order(buy_order).await {
Err(e) if e.to_string().contains("No `quote_spend_limits` entry") => {
// block trading this pair until an operator configures a ceiling
disable_pair(token_in, token_out);
Err(e)
}
r => r,
} Prevention
- Maintain spend-limit entries for every BUY pair enabled in trading config
- Key limits on exact token addresses used by pools (consistent checksum/case)
- Add a config validation pass at startup that cross-checks tradable pairs against quote_spend_limits
When it happens
Trigger: `submit_order()` -> `prepare_swap()` with `order.order_side() == OrderSide::Buy` and no `quote_spend_limits` map entry keyed by the exact (token_in, token_out) address pair.
Common situations: Configured spend limits for the inverse direction only; token address casing/checksum mismatch as map key; new market added to trading config without adding its spend-limit entry.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Quote spend limit for {token_in} -> {token_out} is denominat
- Quote spend limit for token {} uses {} decimals, expected po
- No quote spend ceiling for BUY token pair {} -> {}
- No deployed bytecode at {description} address {address}
- Router allowance {allowance} is below the swap amount {} for
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e1cc7a8e9a047665.
Report an issue: GitHub.