{"record":{"id":"f384bdc54780a4fa","repo":"nautechsystems/nautilus_trader","slug":"invalid-symbol-format-missing-quote-currency-in","errorCode":null,"errorMessage":"Invalid symbol format: missing quote currency in '{symbol}'","messagePattern":"Invalid symbol format: missing quote currency in '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/okx/src/common/parse.rs","lineNumber":291,"sourceCode":"        _ if dash_count > 4 => OKXInstrumentType::Events,\n        _ => OKXInstrumentType::Spot, // Default fallback\n    }\n}\n\n/// Extracts base and quote currencies from an OKX symbol.\n///\n/// All OKX instrument symbols start with {BASE}-{QUOTE}, regardless of type.\n///\n/// # Errors\n///\n/// Returns an error if the symbol doesn't contain at least two parts separated by '-'.\npub fn parse_base_quote_from_symbol(symbol: &str) -> anyhow::Result<(&str, &str)> {\n    let mut parts = symbol.split('-');\n    let base = parts.next().ok_or_else(|| {\n        anyhow::anyhow!(\"Invalid symbol format: missing base currency in '{symbol}'\")\n    })?;\n    let quote = parts.next().ok_or_else(|| {\n        anyhow::anyhow!(\"Invalid symbol format: missing quote currency in '{symbol}'\")\n    })?;\n    Ok((base, quote))\n}\n\n/// Extracts the instrument family from an OKX symbol string.\n///\n/// All OKX derivative symbols encode the family as the first two segments:\n/// `BTC-USD-250328-92000-C` -> `BTC-USD`, `BTC-USDT-SWAP` -> `BTC-USDT`.\n///\n/// # Errors\n///\n/// Returns an error if the symbol does not contain at least two dash-separated parts.\npub fn extract_inst_family(symbol: &str) -> anyhow::Result<Ustr> {\n    let (base, quote) = parse_base_quote_from_symbol(symbol)?;\n    Ok(Ustr::from(&format!(\"{base}-{quote}\")))\n}\n\n/// Maps an [`OKXInstrumentStatus`] to a Nautilus [`MarketStatusAction`].","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/common/parse.rs#L273-L309","documentation":"The sibling failure of 3406: after extracting the base part from an OKX symbol, parse_base_quote_from_symbol requires a second '-'-separated segment for the quote currency. If the symbol contains no '-' (e.g. 'BTCUSDT' or 'BTC-'), no quote can be extracted and this error is returned.","triggerScenarios":"extract_inst_family, parse_position_status_report, subscribe/unsubscribe_index_prices, or request_index_price receives a symbol without a '-' separator, such as a concatenated symbol ('BTCUSDT'), a bare coin id, or a trailing-dash string.","commonSituations":"Configuring instrument ids in compact form ('BTC-USDT' written as 'BTCUSDT'); reusing symbols from another exchange's format (Binance-style); using swap ticker instead of the full instId; copy-paste dropping part of the instrument id.","solutions":["Use OKX's exact instId format with the dash: 'BTC-USDT', 'ETH-USDT-SWAP', 'BTC-USD-240329' — not concatenated or Binance-style symbols.","Validate symbol format (must contain '-') before calling any API that takes it.","Fetch valid instrument ids from the OKX /public/instruments endpoint instead of constructing them by hand.","Normalize symbols at configuration load time and fail early with a clear config error if they don't match the OKX format."],"exampleFix":"// before\nlet symbol = \"BTCUSDT\"; // Binance-style\nparse_base_quote_from_symbol(symbol)?;\n\n// after\nlet symbol = \"BTC-USDT\"; // OKX instId format\nparse_base_quote_from_symbol(symbol)?;","handlingStrategy":"validation","validationCode":"fn is_okx_inst_id(s: &str) -> bool {\n    let parts: Vec<&str> = s.split('-').collect();\n    parts.len() >= 2 && parts.iter().all(|p| !p.is_empty())\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = parse_base_quote_from_symbol(symbol) {\n    anyhow::bail!(\"'{symbol}' is not an OKX instId (expected BASE-QUOTE[-...]): {e}\");\n}","preventionTips":["Always use dash-separated OKX instIds ('BTC-USDT'), never concatenated or Binance-style symbols.","Reject non-conforming symbols during configuration parsing with a clear message.","Cross-check configured ids against the instruments endpoint at startup."],"tags":["rust","okx","symbol-parsing","input-validation"],"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-14T05:17:10.506Z"}