nautechsystems/nautilus_trader · error
Unsupported order side {}; only Buy and Sell are supported
Error message
Unsupported order side {}; only Buy and Sell are supported What it means
prepare_swap only supports OrderSide::Buy and OrderSide::Sell; any other side value is rejected. A swap always moves value in one direction, so both a side must be present and it must be one of the two directional values.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1559
/// Validates a submit-order command against the configured policy and builds the swap plan.
///
/// Local checks run first: pool resolution, order semantics, allowlists, amount and
/// slippage limits, and the quote derived from the live pool profiler. Infrastructure
/// readiness (connection, in-flight slot, durable store, signer) follows. Chain state is
/// verified in the spawned task before signing.
fn prepare_swap(&self, cmd: &SubmitOrder, order: &OrderAny) -> anyhow::Result<SwapPlan> {
let instrument_id = order.instrument_id();
let pool = self.resolve_pool(&instrument_id)?;
if order.order_type() != OrderType::Market {
anyhow::bail!(
"Unsupported order type {}; only Market is supported",
order.order_type()
);
}
if !matches!(order.order_side(), OrderSide::Buy | OrderSide::Sell) {
anyhow::bail!(
"Unsupported order side {}; only Buy and Sell are supported",
order.order_side()
);
}
if order.is_quote_quantity() {
anyhow::bail!(
"Quote-denominated quantities are not supported; quantity must be denominated in the base token"
);
}
let fee = pool
.fee
.ok_or_else(|| anyhow::anyhow!("Pool {instrument_id} has no fee tier"))?;
let fee = U24::try_from(fee)
.map_err(|_| anyhow::anyhow!("Pool {instrument_id} fee {fee} exceeds uint24"))?;
let base_token = pool.get_base_token();View on GitHub (pinned to 18893faf8b)
Solutions
- Set order_side explicitly to OrderSide::Buy or OrderSide::Sell before submitting.
- Validate/normalize the side when ingesting orders from external systems before they reach submit_order.
Example fix
// before let order = OrderAny::default(); // side unset client.submit_order(cmd, &order)?; // after let mut order = OrderAny::default(); order.set_order_side(OrderSide::Buy); client.submit_order(cmd, &order)?;
Defensive patterns
Strategy: validation
Validate before calling
// Rust
if !matches!(order.order_side(), OrderSide::Buy | OrderSide::Sell) {
return Err(anyhow::anyhow!("order side must be Buy or Sell"));
} Prevention
- Always set order side explicitly when constructing orders programmatically.
- Validate sides when deserializing external order payloads.
- Use exhaustive matches on OrderSide in strategy code.
When it happens
Trigger: submit_order called with an order whose order_side() is neither Buy nor Sell (e.g. an uninitialized/default side, or a side variant from another venue vocabulary).
Common situations: Constructing orders programmatically and forgetting to set the side; deserializing orders from an external system where the side field maps to a different variant; copying order-construction code from a venue with different side semantics.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- No deployed bytecode at {description} address {address}
- Finalized Swap side {} does not match Sell order
- HyperSync parsing of swap event is not defined in this dex:
- Unsupported order type {}; only Market is supported
- Quote-denominated quantities are not supported; quantity mus
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/72d6486c509ef774.
Report an issue: GitHub.