nautechsystems/nautilus_trader · warning
Unsupported SBE order side: {side}
Error message
Unsupported SBE order side: {side} What it means
map_side converts the SBE order-side enum into the crate's BinanceSide and bails on any variant other than Buy or Sell. The decoded payload carried an order side the adapter does not model — typically the SBE NULL_VALUE sentinel or a variant added by a schema update.
Source
Thrown at crates/adapters/binance/src/spot/websocket/trading/decode_sbe.rs:425
fn map_order_status(os: order_status::OrderStatus) -> BinanceOrderStatus {
match os {
order_status::OrderStatus::New => BinanceOrderStatus::New,
order_status::OrderStatus::PartiallyFilled => BinanceOrderStatus::PartiallyFilled,
order_status::OrderStatus::Filled => BinanceOrderStatus::Filled,
order_status::OrderStatus::Canceled => BinanceOrderStatus::Canceled,
order_status::OrderStatus::PendingCancel => BinanceOrderStatus::PendingCancel,
order_status::OrderStatus::Rejected => BinanceOrderStatus::Rejected,
order_status::OrderStatus::Expired => BinanceOrderStatus::Expired,
order_status::OrderStatus::ExpiredInMatch => BinanceOrderStatus::ExpiredInMatch,
_ => BinanceOrderStatus::Unknown,
}
}
fn map_side(side: order_side::OrderSide) -> anyhow::Result<BinanceSide> {
match side {
order_side::OrderSide::Buy => Ok(BinanceSide::Buy),
order_side::OrderSide::Sell => Ok(BinanceSide::Sell),
_ => anyhow::bail!("Unsupported SBE order side: {side}"),
}
}
fn map_time_in_force(tif: time_in_force::TimeInForce) -> BinanceTimeInForce {
match tif {
time_in_force::TimeInForce::Gtc => BinanceTimeInForce::Gtc,
time_in_force::TimeInForce::Ioc => BinanceTimeInForce::Ioc,
time_in_force::TimeInForce::Fok => BinanceTimeInForce::Fok,
_ => BinanceTimeInForce::Unknown,
}
}
fn map_order_type(ot: order_type::OrderType) -> &'static str {
match ot {
order_type::OrderType::Market => "MARKET",
order_type::OrderType::Limit => "LIMIT",
order_type::OrderType::StopLoss => "STOP_LOSS",
order_type::OrderType::StopLossLimit => "STOP_LOSS_LIMIT",View on GitHub (pinned to 18893faf8b)
Solutions
- Update codecs/adapter to map any newly added side variant
- Handle NULL_VALUE by treating it as Unknown or skipping the message upstream
- Check which message type was decoded — if side is genuinely absent, decode with the correct type
- Log the raw discriminant to confirm it is the null sentinel
Defensive patterns
Strategy: try-catch
Try / catch
match decode_execution_report(&payload) {
Err(e) if e.to_string().starts_with("Unsupported SBE order side") => {
log::debug!("null/unknown order side; skipping");
}
other => other?,
} Prevention
- Expect NULL_VALUE sides on messages where side is not applicable
- Regenerate enums when the schema adds variants
- Log the raw discriminant before failing
- Route messages to the decoder matching their actual template ID
When it happens
Trigger: Decoding an execution report whose order_side field is the SBE enum's NULL_VALUE/default, or contains a new side variant absent from the generated order_side::OrderSide enum match.
Common situations: Message types where side is not applicable (e.g. cancel acknowledgments) decode with a null side; stale generated codecs after a Binance schema change; zeroed test fixtures.
Related errors
- Unsupported SBE execution type: {et}
- Invalid NodeState value
- Invalid `ConnectionMode` value: {value}
- Wrong template ID: expected {balance_update_event_codec::SBE
- Invalid `BookAction`, was '{invalid}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fcd26057bf46ed93.
Report an issue: GitHub.