nautechsystems/nautilus_trader · error
Unknown order direction: {}
Error message
Unknown order direction: {} What it means
Deribit user-order websocket messages include a `direction` field that must be "buy" or "sell". `parse_user_order_msg` maps this to Nautilus `OrderSide::Buy`/`Sell`. Any other string means the message cannot be translated into an OrderStatusReport, so the parse fails with this error.
Source
Thrown at crates/adapters/deribit/src/websocket/parse.rs:721
/// Parses a Deribit user order message into a Nautilus `OrderStatusReport`.
///
/// # Errors
///
/// Returns an error if the order data cannot be parsed.
pub fn parse_user_order_msg(
msg: &DeribitOrderMsg,
instrument: &InstrumentAny,
account_id: AccountId,
ts_init: UnixNanos,
) -> anyhow::Result<OrderStatusReport> {
let instrument_id = instrument.id();
let venue_order_id = VenueOrderId::new(&msg.order_id);
let order_side = match msg.direction.as_str() {
"buy" => OrderSide::Buy,
"sell" => OrderSide::Sell,
_ => anyhow::bail!("Unknown order direction: {}", msg.direction),
};
// Map Deribit order type to Nautilus
let order_type = parse_deribit_order_type(&msg.order_type);
// Deribit supports: good_til_cancelled, good_til_day, fill_or_kill, immediate_or_cancel
let time_in_force = match msg.time_in_force.as_str() {
"good_til_cancelled" => TimeInForce::Gtc,
"good_til_day" => TimeInForce::Gtd,
"fill_or_kill" => TimeInForce::Fok,
"immediate_or_cancel" => TimeInForce::Ioc,
other => {
log::warn!("Unknown time_in_force '{other}', defaulting to GTC");
TimeInForce::Gtc
}
};
// Map Deribit order state to Nautilus statusView on GitHub (pinned to 18893faf8b)
Solutions
- Log the raw message and inspect the actual `direction` value to see why it deviates
- Normalize direction to lowercase "buy"/"sell" before passing the message to the parser
- Update/patch the adapter if Deribit introduced a new direction value; otherwise treat the message as unparseable and skip it
Example fix
// before
let msg = DeribitOrderMsg { direction: "Buy".to_string(), .. };
let report = parse_user_order_msg(&msg, &instrument)?; // errors
// after
let msg = DeribitOrderMsg { direction: msg.direction.to_lowercase(), .. };
let report = parse_user_order_msg(&msg, &instrument)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_direction(d: &str) -> bool { matches!(d, "buy" | "sell") } Type guard
fn is_valid_direction(d: &str) -> bool { matches!(d, "buy" | "sell") } Try / catch
match parse_user_order_msg(&msg, &instrument) {
Ok(report) => { /* use report */ }
Err(e) => tracing::error!(order_id = %msg.order_id, %e, "dropping unparseable order message"),
} Prevention
- Normalize direction to lowercase before parsing
- Log raw payloads for dropped messages to catch Deribit schema changes
- Favor the adapter's own deserialization over hand-built test messages
When it happens
Trigger: Calling `parse_user_order_msg` (directly or via `process_raw_message`/`generate_order_status_report`) with an order message whose `direction` is neither "buy" nor "sell" — e.g. an empty string, a changed/renamed field from Deribit, or a hand-crafted test payload.
Common situations: Deribit protocol changes or new order message variants; bugs in locally deserialized JSON (wrong field mapped to `direction`); constructing synthetic Deribit messages in tests or simulators with incorrect casing like "Buy".
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 Deribit resolution: {resolution}
- Unknown trade direction: {}
- InstrumentState channel requires kind and currency parameter
- errors joined with "; " (aggregated disconnect errors)
- errors joined with "; " (aggregated disconnect errors)
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/24754c3e02dd5250.
Report an issue: GitHub.