nautechsystems/nautilus_trader · error · anyhow::Error

No symbols provided

Error message

No symbols provided

What it means

The Databento live client's `subscribe` method requires at least one instrument ID. It maps instrument IDs to symbols and calls `symbols.first()`, returning this error if the resulting list is empty, because `stype_in` inference (when not explicitly provided) needs a symbol. This is a local guard before sending the subscription command to the live feed.

Source

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

        stype_in: Option<String>,
    ) -> anyhow::Result<()> {
        if let Some(precisions) = &price_precisions
            && precisions.len() != instrument_ids.len()
        {
            anyhow::bail!(
                "`price_precisions` length ({}) must match `instrument_ids` length ({})",
                precisions.len(),
                instrument_ids.len()
            );
        }

        let symbols: Vec<String> = instrument_ids
            .iter()
            .map(|id| id.symbol.to_string())
            .collect();
        let first_symbol = symbols
            .first()
            .ok_or_else(|| anyhow::anyhow!("No symbols provided"))?;
        let stype_in = match stype_in {
            Some(stype_in) => dbn::SType::from_str(&stype_in)?,
            None => infer_symbology_type(first_symbol),
        };
        let symbols: Vec<&str> = symbols.iter().map(String::as_str).collect();
        check_consistent_symbology(symbols.as_slice())?;
        let mut sub = Subscription::builder()
            .symbols(symbols)
            .schema(dbn::Schema::from_str(&schema)?)
            .stype_in(stype_in)
            .build();

        if let Some(start) = start {
            sub.start = Some(OffsetDateTime::from_unix_timestamp_nanos(i128::from(
                start,
            ))?);
        }
        sub.use_snapshot = snapshot.unwrap_or(false);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass at least one InstrumentId to `subscribe`
  2. Guard the call site (Rust or Python) against an empty instrument list before subscribing
  3. In Python, validate `instrument_ids` length before `py_subscribe`
  4. Fix upstream logic that produces an empty instrument list (e.g. load instruments before subscribing)

Example fix

// Python, before
client.py_subscribe([])

// Python, after
if not instrument_ids:
    raise ValueError("subscribe requires at least one instrument_id")
client.py_subscribe(instrument_ids)
Defensive patterns

Strategy: validation

Validate before calling

# Python caller
if not instrument_ids:
    raise ValueError("subscribe requires at least one instrument_id")

Type guard

def has_instruments(ids: list) -> bool:
    return len(ids) > 0 and all(hasattr(i, "symbol") for i in ids)

Try / catch

try:
    client.py_subscribe(instrument_ids)
except RuntimeError as e:
    if "No symbols provided" in str(e):
        log.error("subscribe called with empty instrument list")
    else:
        raise

Prevention

When it happens

Trigger: Calling `subscribe` (or `py_subscribe`) with an empty `instrument_ids` collection — e.g. `subscribe(&[], ...)` or a Python call with an empty list `[]`.

Common situations: Python callers passing `[]` because instruments were not yet loaded or were filtered out; a strategy subscribing before its instrument definitions arrive; wiring bugs passing an empty list variable.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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