nautechsystems/nautilus_trader · error
Invalid symbol format: missing base currency in '{symbol}'
Error message
Invalid symbol format: missing base currency in '{symbol}' What it means
parse_base_quote_from_symbol splits an OKX instrument id like 'BTC-USDT' or 'BTC-USD-240329' on '-' and extracts base and quote. Although split() on a non-empty string always yields a first element, the code guards with ok_or_else; this 'missing base currency' error represents a malformed/empty symbol input where no base part could be extracted.
Source
Thrown at crates/adapters/okx/src/common/parse.rs:288
OKXInstrumentType::Events
}
}
_ if dash_count > 4 => OKXInstrumentType::Events,
_ => OKXInstrumentType::Spot, // Default fallback
}
}
/// Extracts base and quote currencies from an OKX symbol.
///
/// All OKX instrument symbols start with {BASE}-{QUOTE}, regardless of type.
///
/// # Errors
///
/// Returns an error if the symbol doesn't contain at least two parts separated by '-'.
pub fn parse_base_quote_from_symbol(symbol: &str) -> anyhow::Result<(&str, &str)> {
let mut parts = symbol.split('-');
let base = parts.next().ok_or_else(|| {
anyhow::anyhow!("Invalid symbol format: missing base currency in '{symbol}'")
})?;
let quote = parts.next().ok_or_else(|| {
anyhow::anyhow!("Invalid symbol format: missing quote currency in '{symbol}'")
})?;
Ok((base, quote))
}
/// Extracts the instrument family from an OKX symbol string.
///
/// All OKX derivative symbols encode the family as the first two segments:
/// `BTC-USD-250328-92000-C` -> `BTC-USD`, `BTC-USDT-SWAP` -> `BTC-USDT`.
///
/// # Errors
///
/// Returns an error if the symbol does not contain at least two dash-separated parts.
pub fn extract_inst_family(symbol: &str) -> anyhow::Result<Ustr> {
let (base, quote) = parse_base_quote_from_symbol(symbol)?;
Ok(Ustr::from(&format!("{base}-{quote}")))View on GitHub (pinned to 18893faf8b)
Solutions
- Validate the instrument id is non-empty and matches the OKX format BASE-QUOTE[-DATE] before calling (regex like ^[A-Za-z0-9]+-[A-Za-z0-9]+(-\d{6})?$).
- Check where the symbol originates — config instrument_ids, subscription messages, or position reports — and fix the empty source value.
- Use the instrument id exactly as OKX returns it (e.g. from the instruments endpoint) instead of hand-building the string.
- If OKX deserialization yields an empty instId, check the adapter's message schema against the current OKX API docs for renamed fields.
Example fix
// before
parse_base_quote_from_symbol(&inst_id)?;
// after
if inst_id.is_empty() || !inst_id.contains('-') {
return Err(anyhow::anyhow!("invalid OKX instrument id: '{inst_id}'"));
}
parse_base_quote_from_symbol(&inst_id)?; Defensive patterns
Strategy: validation
Validate before calling
fn valid_okx_symbol(s: &str) -> bool {
!s.is_empty() && s.split('-').next().map(|p| !p.is_empty()).unwrap_or(false)
} Try / catch
match parse_base_quote_from_symbol(symbol) {
Ok((base, quote)) => (base, quote),
Err(e) => return Err(anyhow::anyhow!("bad instrument id '{symbol}': {e}")),
} Prevention
- Validate instrument ids against the OKX format at config-load time.
- Source instrument ids from the OKX instruments endpoint rather than hand-building them.
- Guard against empty strings from uninitialized config or renamed payload fields.
When it happens
Trigger: Called from extract_inst_family, parse_position_status_report, subscribe/unsubscribe_index_prices, or request_index_price with a symbol string that is empty or otherwise yields no base segment before the first '-' (empty string input is the practical trigger).
Common situations: Passing an empty instrument id from an uninitialized config or a subscription event with a blank instId; a bug upstream that forwards None-as-empty-string symbols; constructing symbols manually and forgetting the instType/instId convention; OKX payload field renamed so the symbol field read as empty.
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 symbol format: missing quote currency in '{symbol}'
- instrument update lock poisoned
- option_summary_family_subs mutex poisoned
- Conditional order types must use OKXAlgoOrderType
- Invalid `OrderType` cannot be represented on OKX: {value:?}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/81876d854a4e4e6b.
Report an issue: GitHub.