nautechsystems/nautilus_trader · error

Inconsistent symbology types: '{first_stype}' for {first_sym

Error message

Inconsistent symbology types: '{first_stype}' for {first_symbol} vs '{next_stype}' for {symbol}

What it means

Databento range requests require all symbols to use the same symbology type (e.g. raw, smart, continuous, parent). check_consistent_symbology infers each symbol's stype and fails if they differ, since a single request stype cannot serve mixed types.

Source

Thrown at crates/adapters/databento/src/symbology.rs:188

    }

    SType::RawSymbol
}

/// # Errors
///
/// Returns an error if `symbols` is empty or symbols have inconsistent symbology types.
pub fn check_consistent_symbology(symbols: &[&str]) -> anyhow::Result<()> {
    if symbols.is_empty() {
        anyhow::bail!("No symbols provided");
    }
    let first_symbol = symbols[0];
    let first_stype = infer_symbology_type(first_symbol);

    for symbol in symbols {
        let next_stype = infer_symbology_type(symbol);
        if next_stype != first_stype {
            anyhow::bail!(
                "Inconsistent symbology types: '{first_stype}' for {first_symbol} vs '{next_stype}' for {symbol}"
            );
        }
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use rstest::*;

    use super::*;

    #[rstest]
    #[case("1", "instrument_id")]
    #[case("123456789", "instrument_id")]
    #[case("AAPL", "raw_symbol")]

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Normalize all symbols to one symbology type before the call
  2. Split the request into multiple calls grouped by symbology type
  3. Use explicit stype-in-encoded-symbol syntax (e.g. 'continuous:ES') consistently
  4. Review how symbols are collected to avoid mixed conventions

Example fix

// before
get_range_trades(&["ES.c.0", "ESZ5"], SType::Raw)  // mixed
// after
get_range_trades(&["ES.c.0"], SType::Continuous)
get_range_trades(&["ESZ5"], SType::Raw)
Defensive patterns

Strategy: validation

Validate before calling

let stypes: HashSet<_> = symbols.iter().map(|s| infer_symbology_type(s)).collect();
assert!(stypes.len() == 1, "mixed symbology types: {:?}", stypes);

Try / catch

match get_range_trades(&symbols, stype).await {
    Err(e) if e.to_string().contains("Inconsistent symbology types") => {
        // split into per-stype groups and retry each
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling a get_range_* function with symbols mixing conventions, e.g. ["ESZ5", "ES.c.0"] (raw + continuous) or mixing smart and parent ids.

Common situations: Combining symbols from different config sources or user input; confusing Databento stype conventions; merging symbol lists built with different inference rules.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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