nautechsystems/nautilus_trader · critical
Invalid `OrderType`
Error message
Invalid `OrderType`
What it means
When hydrating an order from a SQL row, the `order_type` column string is parsed with `OrderType::from_str` and the result is unwrapped with expect(). The library panics because an order type stored in the database does not map to any known `OrderType` variant — Nautilus treats the DB row as trusted and considers a corrupt enum value unrecoverable for that row.
Source
Thrown at crates/infrastructure/src/sql/models/orders.rs:1058
let venue_order_id = row
.try_get::<Option<&str>, _>("venue_order_id")
.ok()
.and_then(|x| x.map(VenueOrderId::from));
let position_id = row
.try_get::<Option<&str>, _>("position_id")
.ok()
.and_then(|x| x.map(PositionId::from));
let account_id = row
.try_get::<Option<&str>, _>("account_id")
.ok()
.and_then(|x| x.map(AccountId::from));
let last_trade_id = row
.try_get::<Option<&str>, _>("last_trade_id")
.ok()
.and_then(|x| x.map(TradeId::from));
let order_type = row
.try_get::<&str, _>("order_type")
.map(|x| OrderType::from_str(x).expect("Invalid `OrderType`"))?;
let order_side = row
.try_get::<&str, _>("order_side")
.map(|x| OrderSide::from_str(x).expect("Invalid `OrderSide`"))?;
let quantity = row.try_get::<&str, _>("quantity").map(Quantity::from)?;
let price = row
.try_get::<Option<&str>, _>("price")
.ok()
.and_then(|x| x.map(Price::from));
let activation_price = row
.try_get::<Option<&str>, _>("activation_price")
.ok()
.and_then(|x| x.map(Price::from));
let trigger_price = row
.try_get::<Option<&str>, _>("trigger_price")
.ok()
.and_then(|x| x.map(Price::from));
let trigger_type = row
.try_get::<Option<&str>, _>("trigger_type")View on GitHub (pinned to 18893faf8b)
Solutions
- Query the offending row (`SELECT id, order_type FROM orders WHERE order_type NOT IN (...)`) and fix or delete it
- Check the writer path — ensure orders are inserted using OrderType's canonical serialization (Display/AsRefStr), not adapter strings
- Update nautilus or the adapter so the enum variant exists before reading rows written with newer values
- Replace expect with proper error propagation (`?` with a mapped error) if you control a fork of this model
Example fix
// before
OrderType::from_str(x).expect("Invalid `OrderType`")
// after
OrderType::from_str(x).map_err(|e| ModelError::Parse(format!("invalid order_type '{x}': {e}")))? Defensive patterns
Strategy: type-guard
Validate before calling
const VALID_ORDER_TYPES: &[&str] = &["MARKET","LIMIT","STOP_MARKET","STOP_LIMIT","MARKET_TO_LIMIT","MARKET_IF_TOUCHED","LIMIT_IF_TOUCHED","TRAILING_STOP_MARKET","TRAILING_STOP_LIMIT"]; assert!(VALID_ORDER_TYPES.contains(&order_type_str));
Type guard
fn is_known_order_type(s: &str) -> bool {
OrderType::from_str(s).is_ok()
} Try / catch
let order_type = OrderType::from_str(x)
.map_err(|e| ModelError::Parse(format!("row {}: invalid order_type '{x}': {e}", row_id)))?; Prevention
- Only write enum values via nautilus canonical serialization, never raw adapter strings
- Add a CHECK constraint on order_type in the schema
- Validate enum strings at insertion boundaries
- Re-migrate data after upgrading nautilus versions
When it happens
Trigger: Calling `OrderModel::from_row` (during query deserialization of orders) where the `order_type` column contains a string not in the OrderType enum (wrong case, truncated value, vendor-specific type like 'STOP_LOSS_LIMIT' not modeled, or NULL-handling surprises).
Common situations: Schema written by a different nautilus version or another trading system sharing the table; manual SQL inserts/updates; adapters writing adapter-specific order type strings instead of the canonical nautilus values.
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
- Invalid `OrderSide`
- Invalid `TimeInForce`
- Invalid `LiquiditySide`
- Invalid `OrderStatus`
- Invalid `TriggerType`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fc1197acb1e3abe2.
Report an issue: GitHub.