nautechsystems/nautilus_trader · error

custom data request requires `instrument_id` metadata

Error message

custom data request requires `instrument_id` metadata

What it means

Binance futures custom data types (liquidation stream 'BinanceFuturesLiquidation', open interest history, mark-price style requests) are identified by metadata on the DataType rather than by the type name alone. required_instrument_id_metadata bails when the metadata map lacks a non-empty 'instrument_id' string, because the request cannot be scoped to a symbol without it.

Source

Thrown at crates/adapters/binance/src/futures/data.rs:432

            return Ok(None);
        };

        let instrument_id = InstrumentId::from_str(raw_instrument_id)
            .with_context(|| format!("invalid instrument_id metadata `{raw_instrument_id}`"))?;

        Ok(Some(instrument_id))
    }

    fn required_instrument_id_metadata(data_type: &DataType) -> anyhow::Result<InstrumentId> {
        let Some(raw_instrument_id) = data_type
            .metadata()
            .as_ref()
            .and_then(|m| m.get("instrument_id"))
            .and_then(|v| v.as_str())
            .map(str::trim)
            .filter(|value| !value.is_empty())
        else {
            anyhow::bail!("custom data request requires `instrument_id` metadata");
        };

        InstrumentId::from_str(raw_instrument_id)
            .with_context(|| format!("invalid instrument_id metadata `{raw_instrument_id}`"))
    }

    fn required_period_metadata(data_type: &DataType) -> anyhow::Result<String> {
        let Some(period) = data_type
            .metadata()
            .as_ref()
            .and_then(|m| m.get("period"))
            .and_then(|v| v.as_str())
            .map(str::trim)
            .filter(|value| !value.is_empty())
        else {
            anyhow::bail!("historical open interest request requires `period` metadata");
        };

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Include a metadata entry 'instrument_id' with the full instrument ID string, e.g. metadata={'instrument_id': 'BTCUSDT-PERP.BINANCE'}.
  2. Prefer the adapter's higher-level subscribe/request methods which build the DataType (and its metadata) for you, mirroring liquidation_data_type() in futures/data.rs.
  3. Verify the value parses as an InstrumentId (SYMBOL.VENUE) since an invalid string fails with the adjacent 'invalid instrument_id metadata' context error.

Example fix

# before
from nautilus_trader.core.data import Data
client.subscribe(DataType('BinanceFuturesLiquidation'))

# after
metadata = {'instrument_id': 'BTCUSDT-PERP.BINANCE'}
client.subscribe(DataType('BinanceFuturesLiquidation', metadata=metadata))
Defensive patterns

Strategy: validation

Validate before calling

def custom_data_with_instrument(data_type_name: str, instrument_id: str) -> 'DataType':
    assert instrument_id and '.' in instrument_id  # SYMBOL.VENUE
    return DataType(data_type_name, metadata={'instrument_id': instrument_id})

# usage
client.subscribe(custom_data_with_instrument('BinanceFuturesLiquidation', 'BTCUSDT-PERP.BINANCE'))

Type guard

def has_required_custom_metadata(data_type) -> bool:
    md = dict(data_type.metadata or {})
    return isinstance(md.get('instrument_id'), str) and bool(md['instrument_id'].strip())

Try / catch

try:
    client.subscribe(data_type)
except Exception as e:
    if 'requires `instrument_id` metadata' in str(e):
        data_type = DataType(data_type.topic, metadata={'instrument_id': 'BTCUSDT-PERP.BINANCE'})
        client.subscribe(data_type)
    else:
        raise

Prevention

When it happens

Trigger: Calling subscribe / request on the futures data client with a hand-built DataType for a Binance custom stream that omits metadata, e.g. DataType('BinanceFuturesLiquidation') with no metadata, or metadata={'instrument_id': ''} / a non-string value.

Common situations: Constructing the custom DataType manually instead of using the adapter's provided request/subscription helpers; passing metadata keys with different names ('symbol', 'instrument'); trailing-whitespace or empty-string instrument_id from templated configs.

Related errors


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