{"record":{"id":"5cd174d32e287ae0","repo":"nautechsystems/nautilus_trader","slug":"invalid-option-symbol-symbol","errorCode":null,"errorMessage":"invalid option symbol '{symbol}'","messagePattern":"invalid option symbol '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/common/parse.rs","lineNumber":1363,"sourceCode":"        Err(anyhow::anyhow!(\n            \"unrecognized settlement currency '{settle_coin}'\"\n        ))\n    }\n}\n\n/// Returns a currency from the internal map or creates a new crypto currency.\n///\n/// Uses [`Currency::get_or_create_crypto`] to handle unknown currency codes,\n/// which automatically registers newly listed Bybit assets.\npub fn get_currency(code: &str) -> Currency {\n    Currency::get_or_create_crypto(code)\n}\n\nfn extract_strike_from_symbol(symbol: &str) -> anyhow::Result<Price> {\n    let parts: Vec<&str> = symbol.split('-').collect();\n    let strike = parts\n        .get(2)\n        .ok_or_else(|| anyhow::anyhow!(\"invalid option symbol '{symbol}'\"))?;\n    parse_price(strike, \"option strike\")\n}\n\n/// Resolves a Nautilus [`OrderType`] from Bybit order classification fields.\n///\n/// Bybit represents conditional orders using a combination of `orderType` (Market/Limit),\n/// `stopOrderType` (Stop, TakeProfit, StopLoss, etc.), `triggerDirection` (RisesTo/FallsTo),\n/// and `side` (Buy/Sell). This function maps all combinations to the appropriate Nautilus\n/// conditional order types.\n///\n/// When `triggerDirection` is `None`, the stop order type is informational only (a parent\n/// order with TP/SL metadata attached), so the order is classified as plain Market/Limit.\n#[must_use]\npub fn parse_bybit_order_type(\n    order_type: BybitOrderType,\n    stop_order_type: BybitStopOrderType,\n    trigger_direction: BybitTriggerDirection,\n    side: BybitOrderSide,","sourceCodeStart":1345,"sourceCodeEnd":1381,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/common/parse.rs#L1345-L1381","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet strike = extract_strike_from_symbol(symbol)?;\n// after\nlet is_option_symbol = symbol.split('-').count() >= 4;\nanyhow::ensure!(is_option_symbol, \"'{symbol}' is not a valid Bybit option symbol\");\nlet strike = extract_strike_from_symbol(symbol)?;","handlingStrategy":"validation","validationCode":"// Rust: verify option symbol shape before extracting strike\nlet re = regex::Regex::new(r\"^[A-Z0-9]+-[A-Z0-9]+-\\d+(\\.\\d+)?-[CP]$\").unwrap();\nanyhow::ensure!(re.is_match(symbol), \"not a Bybit option symbol: {symbol}\");","typeGuard":"fn is_option_symbol(symbol: &str) -> bool {\n    let parts: Vec<&str> = symbol.split('-').collect();\n    parts.len() >= 4 && parts[2].parse::<f64>().is_ok()\n}","tryCatchPattern":"let strike = extract_strike_from_symbol(symbol)\n    .with_context(|| format!(\"failed to parse option symbol {symbol}\"))?;","preventionTips":["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"],"tags":["symbol","options","parsing","bybit"],"backgroundTag":"invalid-identifier-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}