nautechsystems/nautilus_trader · error
Cannot extract market ID from
Error message
Cannot extract market ID from {instrument_id} What it means
extract_market_id parses a Betfair instrument ID whose symbol is expected in the form <marketId>-<selectionId>[-<handicap>]. If the symbol cannot be split into at least two '-'-separated parts, no market ID can be extracted and this error is raised.
Solutions
- Build the instrument ID as '<marketId>-<selectionId>' (optionally '-<handicap>') per Betfair conventions
- Validate the symbol format with extract_market_id/extract_selection_id before use
- Regenerate the instrument ID from the Betfair catalog rather than constructing it manually
Example fix
// before
let instrument_id = InstrumentId::from("BETFAIR.WIN");
// after
let instrument_id = InstrumentId::from("BETFAIR.1.23456789-12345"); Defensive patterns
Strategy: validation
Validate before calling
fn valid_betfair_symbol(symbol: &str) -> bool {
let mut it = symbol.splitn(2, '-');
it.next().map_or(false, |m| !m.is_empty()) && it.next().map_or(false, |s| s.parse::<u64>().is_ok())
} Type guard
fn as_betfair_instrument_id(id: &InstrumentId) -> Option<String> {
extract_market_id(id).ok()
} Try / catch
match extract_market_id(&instrument_id) {
Ok(market_id) => subscribe(market_id).await,
Err(e) => { log::error!("bad Betfair instrument id: {e}"); Err(e) }
} Prevention
- Create Betfair instrument IDs only via the adapter's catalog/symbol conventions
- Validate instrument IDs at config load, before runtime
- Never strip the '-<selectionId>' suffix from Betfair symbols
When it happens
Trigger: Calling extract_market_id (directly or via subscribe_book_deltas, submit_order, cancel_order, modify_order) with an InstrumentId whose symbol contains no '-' separator, e.g. 'BETFAIR' instead of '1.23456789-12345'.
Common situations: Hand-constructing instrument IDs without the market-selection format; using instrument IDs from another adapter; stripping the suffix when normalizing symbols.
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
- Cannot extract selection ID from
- cannot derive currency from
- Cannot expand parent subscription for
- {FAILED}: {e}
- Failed to parse instrument ID from key
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/29985f6e2062b358.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/betfair/src/common/parse.rs:493
)
.with_info(info))
}
/// Extracts the Betfair market ID from a Nautilus instrument ID.
///
/// Instrument IDs follow the format `{market_id}-{selection_id}.BETFAIR`
/// or `{market_id}-{selection_id}-{handicap}.BETFAIR`.
///
/// # Errors
///
/// Returns an error if the symbol does not contain a hyphen separator.
pub fn extract_market_id(instrument_id: &InstrumentId) -> anyhow::Result<String> {
let symbol = instrument_id.symbol.as_str();
let parts: Vec<&str> = symbol.splitn(3, '-').collect();
if parts.len() >= 2 {
Ok(parts[0].to_string())
} else {
anyhow::bail!("Cannot extract market ID from {instrument_id}")
}
}
/// Extracts the selection ID and handicap from a Nautilus instrument ID.
///
/// # Errors
///
/// Returns an error if the symbol cannot be parsed into the expected format.
pub fn extract_selection_id(
instrument_id: &InstrumentId,
) -> anyhow::Result<(SelectionId, Decimal)> {
let symbol = instrument_id.symbol.as_str();
let parts: Vec<&str> = symbol.splitn(3, '-').collect();
if parts.len() < 2 {
anyhow::bail!("Cannot extract selection ID from {instrument_id}");
}
let selection_id: SelectionId = parts[1]View on GitHub (pinned to 18893faf8b)