nautechsystems/nautilus_trader · error · anyhow::Error
invalid option symbol '{symbol}'
Error message
invalid option symbol '{symbol}' What it means
extract_strike_from_symbol parses a Bybit option symbol of the form BASE-QUOTE-STRIKE-EXPIRY (dash-separated) and extracts the strike at index 2 as a Price. This error means the symbol does not have at least three dash-separated components, so no strike can be located.
Source
Thrown at crates/adapters/bybit/src/common/parse.rs:1363
Err(anyhow::anyhow!(
"unrecognized settlement currency '{settle_coin}'"
))
}
}
/// Returns a currency from the internal map or creates a new crypto currency.
///
/// Uses [`Currency::get_or_create_crypto`] to handle unknown currency codes,
/// which automatically registers newly listed Bybit assets.
pub fn get_currency(code: &str) -> Currency {
Currency::get_or_create_crypto(code)
}
fn extract_strike_from_symbol(symbol: &str) -> anyhow::Result<Price> {
let parts: Vec<&str> = symbol.split('-').collect();
let strike = parts
.get(2)
.ok_or_else(|| anyhow::anyhow!("invalid option symbol '{symbol}'"))?;
parse_price(strike, "option strike")
}
/// Resolves a Nautilus [`OrderType`] from Bybit order classification fields.
///
/// Bybit represents conditional orders using a combination of `orderType` (Market/Limit),
/// `stopOrderType` (Stop, TakeProfit, StopLoss, etc.), `triggerDirection` (RisesTo/FallsTo),
/// and `side` (Buy/Sell). This function maps all combinations to the appropriate Nautilus
/// conditional order types.
///
/// When `triggerDirection` is `None`, the stop order type is informational only (a parent
/// order with TP/SL metadata attached), so the order is classified as plain Market/Limit.
#[must_use]
pub fn parse_bybit_order_type(
order_type: BybitOrderType,
stop_order_type: BybitStopOrderType,
trigger_direction: BybitTriggerDirection,
side: BybitOrderSide,View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the symbol is a full Bybit option symbol like 'BTC-28MAR25-65000-C' (4 dash-separated parts).
- Check the category/instrument type used when requesting the instrument matches the symbol type (options vs linear).
- Validate the symbol format before calling option parsing (regex on BASE-QUOTE-STRIKE-TYPE).
- Confirm the symbol exists on Bybit and was not truncated or altered by upstream code.
Example fix
// before
let strike = extract_strike_from_symbol(symbol)?;
// after
let is_option_symbol = symbol.split('-').count() >= 4;
anyhow::ensure!(is_option_symbol, "'{symbol}' is not a valid Bybit option symbol");
let strike = extract_strike_from_symbol(symbol)?; Defensive patterns
Strategy: validation
Validate before calling
// Rust: verify option symbol shape before extracting strike
let re = regex::Regex::new(r"^[A-Z0-9]+-[A-Z0-9]+-\d+(\.\d+)?-[CP]$").unwrap();
anyhow::ensure!(re.is_match(symbol), "not a Bybit option symbol: {symbol}"); Type guard
fn is_option_symbol(symbol: &str) -> bool {
let parts: Vec<&str> = symbol.split('-').collect();
parts.len() >= 4 && parts[2].parse::<f64>().is_ok()
} Try / catch
let strike = extract_strike_from_symbol(symbol)
.with_context(|| format!("failed to parse option symbol {symbol}"))?; Prevention
- Match symbol format to the request category (options vs linear/inverse)
- Validate symbols with a regex like BASE-QUOTE-STRIKE-TYPE before use
- Never truncate or rewrite symbols coming from exchange listings
When it happens
Trigger: parse_option_instrument passes a symbol string where symbol.split('-') has fewer than 3 parts — e.g. a linear/perpetual symbol like 'BTCUSDT' or 'BTCUSDT-240329' accidentally routed to option parsing.
Common situations: Subscribing to an instrument with a non-option symbol type but an option-category request; typo in the symbol string; programmatic symbol construction producing the wrong format; Bybit changing symbol format for some products.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- invalid type for 'order_iv': {value}, expected string or num
- invalid Bybit trigger type: '{s}', expected LastPrice, MarkP
- invalid Bybit TP/SL order type: '{s}', expected Market or Li
- invalid Bybit TP/SL mode: '{s}', expected Full or Partial
- Bybit does not support kline/bar data for options
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5cd174d32e287ae0.
Report an issue: GitHub.