nautechsystems/nautilus_trader · error · anyhow::Error

unsupported Binance instrument filter

Error message

unsupported Binance instrument filter {key:?} for {product_type:?}

What it means

BinanceDataClientConfig::instrument_provider filters are restricted to a whitelist. 'symbols', 'bases', and 'quotes' are always supported, while 'contract_types' is only valid for USD-M and COIN-M futures product types. validate() throws this error when an unknown filter key is supplied or when 'contract_types' is used with a non-futures product type (e.g. Spot).

Solutions

  1. Use only 'symbols', 'bases', or 'quotes' filter keys.
  2. If using 'contract_types', set product_type to BinanceProductType::UsdM or BinanceProductType::CoinM.
  3. For Spot product types, remove 'contract_types' from the instrument filters.
  4. Fix any typos in filter key names.

Example fix

// before
filters.insert("contract_types", json!(["PERPETUAL"])); // product_type: Spot
// after
filters.insert("symbols", json!(["BTCUSDT"])); // or switch product_type to UsdM/CoinM
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_ALWAYS: [&str; 3] = ["symbols", "bases", "quotes"];
fn filters_valid(filters: &[&str], product_type: BinanceProductType) -> bool {
    filters.iter().all(|k| {
        ALLOWED_ALWAYS.contains(k)
            || (*k == "contract_types"
                && matches!(product_type, BinanceProductType::UsdM | BinanceProductType::CoinM))
    })
}

Prevention

When it happens

Trigger: Calling BinanceDataClientConfig::validate() (directly or via request_instruments_with_config) with an instrument_provider config whose filters map contains a key other than symbols/bases/quotes, or containing 'contract_types' while product_type is Spot or another non-futures BinanceProductType.

Common situations: Copying a futures config example into a Spot client setup; typo'd filter keys like 'base' or 'symbol'; forward-porting config from a version that accepted more filter keys.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/config.rs:115

        if let Some(load_ids) = &self.load_ids {
            for raw in load_ids {
                let instrument_id = InstrumentId::from_str(raw)
                    .map_err(|e| anyhow::anyhow!("invalid Binance load_ids value {raw:?}: {e}"))?;
                anyhow::ensure!(
                    instrument_id.venue.as_str() == "BINANCE",
                    "Binance load_ids value {raw:?} must use venue BINANCE"
                );
            }
        }

        for (key, value) in &self.filters {
            let supported = matches!(key.as_str(), "symbols" | "bases" | "quotes")
                || key == "contract_types"
                    && matches!(
                        product_type,
                        BinanceProductType::UsdM | BinanceProductType::CoinM
                    );
            anyhow::ensure!(
                supported,
                "unsupported Binance instrument filter {key:?} for {product_type:?}"
            );
            validate_filter_strings(key, value)?;
        }

        Ok(())
    }
}

fn validate_filter_strings(name: &str, value: &serde_json::Value) -> anyhow::Result<()> {
    let valid = match value {
        serde_json::Value::String(value) => !value.trim().is_empty(),
        serde_json::Value::Array(values) => {
            !values.is_empty()
                && values
                    .iter()
                    .all(|value| value.as_str().is_some_and(|value| !value.trim().is_empty()))

View on GitHub (pinned to 18893faf8b)