nautechsystems/nautilus_trader · error · anyhow::Error

Invalid venue code '{exchange}': {e}

Error message

Invalid venue code '{exchange}': {e}

What it means

The adapter builds a Venue from the Databento exchange string via `Venue::from_code`, which only accepts known/valid venue codes. The exchange string on the record did not map to a valid Nautilus Venue, so the instrument ID translation fails.

Source

Thrown at crates/adapters/databento/src/live.rs:1080

    }

    Ok(())
}

/// Updates the instrument ID map using exchange information from the symbol map.
fn update_instrument_id_map_with_exchange(
    symbol_map: &PitSymbolMap,
    symbol_venue_map: &AtomicMap<Symbol, Venue>,
    instrument_id_map: &mut AHashMap<u32, InstrumentId>,
    raw_instrument_id: u32,
    exchange: &str,
) -> anyhow::Result<InstrumentId> {
    let raw_symbol = symbol_map.get(raw_instrument_id).ok_or_else(|| {
        anyhow::anyhow!("Cannot resolve raw_symbol for instrument_id {raw_instrument_id}")
    })?;
    let symbol = Symbol::from(raw_symbol.as_str());
    let venue = Venue::from_code(exchange)
        .map_err(|e| anyhow::anyhow!("Invalid venue code '{exchange}': {e}"))?;
    let instrument_id = InstrumentId::new(symbol, venue);
    symbol_venue_map.rcu(|m| {
        m.entry(symbol).or_insert(venue);
    });
    instrument_id_map.insert(raw_instrument_id, instrument_id);
    Ok(instrument_id)
}

fn update_instrument_id_map(
    record: &dbn::RecordRef,
    symbol_map: &PitSymbolMap,
    publisher_venue_map: &IndexMap<PublisherId, Venue>,
    symbol_venue_map: &AtomicMap<Symbol, Venue>,
    instrument_id_map: &mut AHashMap<u32, InstrumentId>,
) -> anyhow::Result<InstrumentId> {
    let header = record.header();

    // Check if instrument ID is already in the map

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Disable `use_exchange_as_venue` so the adapter derives the venue from the Databento publisher ID instead of the raw exchange string
  2. Check the exchange string in the error message against the supported venue code list; register or map unknown exchanges before use
  3. Update to the latest nautilus version, which may have added the missing venue code
  4. Sanitize/normalize the exchange string upstream (trim, uppercase) if it comes from custom configuration

Example fix

// before
let venue = Venue::from_code(exchange)
    .map_err(|e| anyhow::anyhow!("Invalid venue code '{exchange}': {e}"))?;
// after: fall back to publisher-derived venue
let venue = Venue::from_code(exchange).unwrap_or_else(|_| {
    log::warn!("Unknown exchange '{exchange}', falling back to publisher venue");
    publisher_venue_map[&publisher_id]
});
Defensive patterns

Strategy: validation

Validate before calling

// validate the exchange code before processing records
let known = ["GLBX", "XNAS", "XNYS", "XCME", "EC4"];
assert!(known.contains(&exchange.to_uppercase().as_str()), "unsupported exchange {exchange}");

Type guard

fn is_valid_venue(code: &str) -> bool { Venue::from_code(code).is_ok() }

Try / catch

match Venue::from_code(exchange) {
    Ok(v) => v,
    Err(e) => return Err(anyhow::anyhow!("configure venue for '{exchange}': {e}")),
}

Prevention

When it happens

Trigger: `update_instrument_id_map_with_exchange` receives an `exchange` string from the symbol map/Databento record that `Venue::from_code` rejects — unknown code, empty string, or a code with invalid characters for a Venue.

Common situations: New or less-common Databento exchanges not present in the venue registry, exchange field empty on the record, `use_exchange_as_venue` enabled for datasets whose exchange labels don't match Nautilus venue codes.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/0b2cc70f770dcf2c. Report an issue: GitHub.