nautechsystems/nautilus_trader · error

Cannot extract market ID from {instrument_id}

Error message

Cannot extract market ID from {instrument_id}

What it means

Betfair instrument symbols encode both a market and a runner: {market_id}-{selection_id} or {market_id}-{selection_id}-{handicap} (e.g. 1.246503964-12345-0.5). extract_market_id splits the symbol on '-' and takes the first segment; with fewer than 2 segments there is no separator and the market id cannot be extracted, so it bails. This runs on execution paths (submit/cancel) and data/provider lookups.

Source

Thrown at crates/adapters/betfair/src/common/parse.rs:507

    )
    .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 a4b06ed870)

Solutions

  1. Always construct ids via make_instrument_id(market_id, selection_id, handicap) instead of string concatenation
  2. If you only hold a market id, it is not an instrument — resolve selections from the market catalogue first, then build the id
  3. Validate the symbol format (>= 2 hyphen-separated parts) before sending orders or data requests
  4. Check the instrument's venue is BETFAIR and the symbol was not truncated by config/env parsing

Example fix

// before
let id = InstrumentId::from("1.246503964.BETFAIR"); // bare market id — no selection
// after
let id = make_instrument_id("1.246503964", 12345, Decimal::ZERO);
Defensive patterns

Strategy: validation

Validate before calling

// Validate Betfair instrument id shape before calling execution/data APIs
fn is_valid_betfair_instrument_id(id: &InstrumentId) -> bool {
    if id.venue.as_str() != "BETFAIR" {
        return false;
    }
    let parts: Vec<&str> = id.symbol.as_str().splitn(3, '-').collect();
    parts.len() >= 2
        && parts[0].split('.').count() == 2 // market id like 1.246503964
        && parts[1].parse::<u64>().is_ok()
        && (parts.len() == 2 || parts[2].parse::<Decimal>().is_ok())
}

if !is_valid_betfair_instrument_id(&instrument_id) {
    anyhow::bail!("refusing order for malformed Betfair instrument {instrument_id}");
}

Try / catch

match extract_market_id(&instrument_id) {
    Ok(market_id) => submit_order(market_id, /* ... */).await,
    Err(e) => {
        log::error!("rejecting order for unparseable instrument {instrument_id}: {e}");
        // do not send; surface to strategy as a rejected command
        Err(e)
    }
}

Prevention

When it happens

Trigger: An InstrumentId built from a bare Betfair market id like 1.246503964 (no -selection suffix); passing an instrument from another venue or a hand-assembled symbol into betfair execution or data requests; stripping the selection component during config or mapping.

Common situations: Users confuse Betfair market ids (dot-separated, 1.xxxxx) with Nautilus instrument ids; strategies subscribe to instruments by market catalogue but orders reference a market id string; symbols mangled by config templating or string transforms that drop hyphens.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/29985f6e2062b358. Report an issue: GitHub.