nautechsystems/nautilus_trader · error · anyhow::Error

on_symbol_mapping failed for {msg:?}: {e}

Error message

on_symbol_mapping failed for {msg:?}: {e}

What it means

When the live feed delivers a `dbn::SymbolMappingMsg`, the feed handler applies it to a point-in-time `PitSymbolMap` via `on_symbol_mapping`. If that mapping update fails, the error is wrapped with the offending message and this text. A failure here means symbol-mapping state (Databento raw symbol to instrument ID) can no longer be trusted for that channel, so decoding subsequent records for that instrument may be wrong.

Source

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

        .strip_circumfix("Subscription request ", " data succeeded")
        .and_then(|rest| rest.split_once(" for "))
        .map(|(_, schema)| schema.trim().to_string())
        .unwrap_or_default()
}

/// Handles symbol mapping messages and updates the instrument ID map.
///
/// # Errors
///
/// Returns an error if symbol mapping fails.
fn handle_symbol_mapping_msg(
    msg: &dbn::SymbolMappingMsg,
    symbol_map: &mut PitSymbolMap,
    instrument_id_map: &mut AHashMap<u32, InstrumentId>,
) -> anyhow::Result<()> {
    symbol_map
        .on_symbol_mapping(msg)
        .map_err(|e| anyhow::anyhow!("on_symbol_mapping failed for {msg:?}: {e}"))?;
    instrument_id_map.remove(&msg.header().instrument_id);
    Ok(())
}

fn update_price_precision_map_with_symbol_mapping_msg(
    msg: &dbn::SymbolMappingMsg,
    price_precision_overrides: &AHashMap<Symbol, u8>,
    subscription_price_precision_map: &mut AHashMap<u32, u8>,
) -> anyhow::Result<()> {
    subscription_price_precision_map.remove(&msg.hd.instrument_id);

    if price_precision_overrides.is_empty() {
        return Ok(());
    }

    let stype_in_symbol = msg
        .stype_in_symbol()
        .map_err(|e| anyhow::anyhow!("Error decoding `stype_in_symbol`: {e}"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the logged `msg` to see the exact SymbolMappingMsg that was rejected
  2. Check the databento crate version matches the server dataset/schema expectations (upgrade if needed)
  3. Verify the stype_in/stype_out combination used at subscribe time is consistent
  4. Clear/reset the symbol map state (restart the session) so the PitSymbolMap is rebuilt cleanly
  5. If persistent, report/reproduce with Databento support — the mapping record may be genuinely malformed

Example fix

// before
symbol_map.on_symbol_mapping(msg)?;

// after
symbol_map
    .on_symbol_mapping(msg)
    .map_err(|e| {
        log::warn!("skipping bad symbol mapping: {e}");
        anyhow::anyhow!("on_symbol_mapping failed for {msg:?}: {e}")
    })?;
Defensive patterns

Strategy: try-catch

Validate before calling

// pin and verify databento crate version against dataset expectations
cargo tree -p databento | grep databento

Try / catch

match feed_result {
    Err(e) if e.to_string().contains("on_symbol_mapping failed") => {
        log::error!("symbol mapping failure: {e:#}");
        // rebuild symbol map / restart session with consistent stype
    }
    other => other?,
}

Prevention

When it happens

Trigger: A symbol mapping record arrives whose content the `PitSymbolMap` rejects — e.g. a mapping inconsistent with previously seen mappings, malformed mapping data in the Databento stream, or a pit-map invariant violation while processing the `SymbolMappingMsg`.

Common situations: Databento schema/symbology changes producing unexpected mapping records; subscribing with stype combinations that yield conflicting mappings; corrupted or out-of-order stream data after reconnects; version drift between the databento crate and server record formats.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — 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/62eedbecf2156ebb. Report an issue: GitHub.