nautechsystems/nautilus_trader · error
Unspecified Bybit order side
Error message
Unspecified Bybit order side
What it means
The `TryFrom<BybitOrderSide>` impl for the domain `OrderSide` rejects `BybitOrderSide::Unknown` with this error, because a side that Bybit did not map to Buy/Sell cannot be converted into a domain order side. It prevents silently treating an unspecified/unknown exchange side as a real direction.
Source
Thrown at crates/adapters/bybit/src/common/enums.rs:653
impl From<BybitOrderSide> for Option<OrderSide> {
fn from(value: BybitOrderSide) -> Self {
match value {
BybitOrderSide::Buy => Some(OrderSide::Buy),
BybitOrderSide::Sell => Some(OrderSide::Sell),
BybitOrderSide::Unknown => None,
}
}
}
impl TryFrom<BybitOrderSide> for OrderSide {
type Error = anyhow::Error;
fn try_from(value: BybitOrderSide) -> Result<Self, Self::Error> {
match value {
BybitOrderSide::Buy => Ok(Self::Buy),
BybitOrderSide::Sell => Ok(Self::Sell),
BybitOrderSide::Unknown => anyhow::bail!("Unspecified Bybit order side"),
}
}
}
impl From<OrderSide> for BybitOrderSide {
fn from(value: OrderSide) -> Self {
match value {
OrderSide::Buy => Self::Buy,
OrderSide::Sell => Self::Sell,
}
}
}
impl From<BybitTriggerType> for TriggerType {
fn from(value: BybitTriggerType) -> Self {
match value {
BybitTriggerType::None => Self::Default,
BybitTriggerType::LastPrice => Self::LastPrice,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the raw Bybit payload's side field and fix the mapping for the new/empty value.
- Update the adapter to a version that recognizes the side string Bybit is sending (API version change).
- Guard the conversion: only convert when `side != BybitOrderSide::Unknown`, otherwise log and skip.
- Check for market-specific quirks (e.g. some instruments report side differently) and normalize upstream.
Example fix
// before
let side: OrderSide = bybit_side.try_into()?;
// after
let side = match bybit_side {
BybitOrderSide::Unknown => { log::warn!("skipping order with unspecified side"); return Ok(()); }
s => s.try_into()?,
}; Defensive patterns
Strategy: validation
Validate before calling
fn order_side_is_known(side: &BybitOrderSide) -> bool {
!matches!(side, BybitOrderSide::Unknown)
}
anyhow::ensure!(order_side_is_known(&bybit_side), "Bybit side missing in payload"); Type guard
fn as_known_side(side: &BybitOrderSide) -> Option<&BybitOrderSide> {
match side {
BybitOrderSide::Unknown => None,
s => Some(s),
}
} Try / catch
match OrderSide::try_from(bybit_side) {
Ok(side) => process(side),
Err(e) if e.to_string().contains("Unspecified Bybit order side") => {
warn!("order update without side; skipping");
}
Err(e) => return Err(e),
} Prevention
- Validate the raw `orderSide` field before constructing domain objects
- Update the adapter when Bybit introduces new side values
- Log the raw payload when conversion fails to spot API changes early
- Skip/queue rather than fail on malformed exchange notifications
When it happens
Trigger: Converting a Bybit order/notification side to the domain type when the raw payload contained an unrecognized or missing side, yielding `BybitOrderSide::Unknown`.
Common situations: Parsing execution/order updates from Bybit whose `orderSide` field is empty or a newly introduced value; older adapter version not knowing a new side string; conditional-order payloads with absent side.
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
- Unsupported `OrderSide` for Binance: {value:?}
- invalid OrderSide: must be Buy or Sell, was {side}
- Invalid order side: {e}
- Finalized Swap side {} does not match Sell order
- Batch cancel limit is {endpoint_limit} orders for {product_t
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/191b323b9923ce43.
Report an issue: GitHub.