nautechsystems/nautilus_trader · error

Invalid trade direction: {other}

Error message

Invalid trade direction: {other}

What it means

parse_trade_tick maps the Deribit public trade direction string to an aggressor side; only 'buy' and 'sell' are accepted, so any other string (or a changed API value) is rejected before price/size parsing proceeds.

Source

Thrown at crates/adapters/deribit/src/common/parse.rs:800

// Parses a Deribit public trade into a Nautilus [`TradeTick`].
///
/// # Errors
///
/// Returns an error if:
/// - The direction is not "buy" or "sell"
/// - Decimal conversion fails for price or size
pub fn parse_trade_tick(
    trade: &DeribitPublicTrade,
    instrument_id: InstrumentId,
    price_precision: u8,
    size_precision: u8,
    ts_init: UnixNanos,
) -> anyhow::Result<TradeTick> {
    // Parse aggressor side from direction
    let aggressor_side = match trade.direction.as_str() {
        "buy" => AggressorSide::Buy,
        "sell" => AggressorSide::Sell,
        other => anyhow::bail!("Invalid trade direction: {other}"),
    };
    let price = Price::from_decimal_dp(trade.price, price_precision)?;
    let size = Quantity::from_decimal_dp(trade.amount, size_precision)?;
    let ts_event = UnixNanos::from((trade.timestamp as u64) * NANOSECONDS_IN_MILLISECOND);
    let trade_id = build_public_trade_id(
        &trade.trade_id,
        trade.block_rfq_id,
        trade.block_trade_id.as_deref(),
        trade.combo_id.as_deref(),
    );

    Ok(TradeTick::new(
        instrument_id,
        price,
        size,
        aggressor_side,
        trade_id,
        ts_event,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the Deribit API docs for new direction values and update the match
  2. Normalize direction casing before matching
  3. Log and skip trades with unknown direction if resilience matters more than strictness

Example fix

// before
other => anyhow::bail!("Invalid trade direction: {other}"),
// after
other => {
    log::warn!("Unknown trade direction '{other}', skipping trade");
    return Ok(None);
}
Defensive patterns

Strategy: validation

Validate before calling

assert!(matches!(trade.direction.as_str(), "buy" | "sell"), "bad direction: {}", trade.direction);

Type guard

fn known_direction(d: &str) -> bool { matches!(d, "buy" | "sell") }

Try / catch

match parse_trade_tick(&trade, ...).await /* or sync */ {
    Err(e) if e.to_string().contains("Invalid trade direction") => {
        warn!("skipping trade with unknown direction");
    }
    other => other?,
}

Prevention

When it happens

Trigger: A Deribit trade tick whose direction field contains an unexpected value (e.g. changed casing, new enum value, or null serialized oddly).

Common situations: Deribit API adding a new direction variant, locale/case changes, corrupted payloads, custom test fixtures with invalid direction strings.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/2d075f71de969898. Report an issue: GitHub.