nautechsystems/nautilus_trader · error · anyhow::Error

filter {key:?} is not a string or array

Error message

filter {key:?} is not a string or array

What it means

Parsing a Binance instrument-loading filter from client config: the filter value must be a JSON string or an array of strings. This error fires when the value itself is neither - a bare number, boolean, null, or object at the top level of the filter key.

Source

Thrown at crates/adapters/binance/src/common/instruments.rs:103

fn filter_values(
    config: &BinanceInstrumentProviderConfig,
    key: &str,
) -> anyhow::Result<Option<AHashSet<String>>> {
    let Some(value) = config.filters.get(key) else {
        return Ok(None);
    };

    let values = match value {
        serde_json::Value::String(value) => vec![value.as_str()],
        serde_json::Value::Array(values) => values
            .iter()
            .map(|value| {
                value
                    .as_str()
                    .ok_or_else(|| anyhow::anyhow!("filter {key:?} contains a non-string value"))
            })
            .collect::<anyhow::Result<Vec<_>>>()?,
        _ => anyhow::bail!("filter {key:?} is not a string or array"),
    };

    Ok(Some(
        values
            .into_iter()
            .map(|value| value.trim().to_ascii_uppercase())
            .collect(),
    ))
}

fn matches_filter(values: &Option<AHashSet<String>>, value: &str) -> bool {
    values.as_ref().is_none_or(|values| contains(values, value))
}

fn contains(values: &AHashSet<String>, value: &str) -> bool {
    values.contains(&value.to_ascii_uppercase())
}

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Wrap the value in quotes (single string form) or make it an array of quoted strings
  2. Re-check every filter key in the client config for correct JSON/YAML typing
  3. Add a config schema check before client construction

Example fix

# before (YAML)
filter_symbols: 1234      # parses as integer

# after
filter_symbols: "1234"    # or ["1234", "5678"]
Defensive patterns

Strategy: validation

Validate before calling

fn filter_key_valid(v: &serde_json::Value) -> bool {
    matches!(v, serde_json::Value::String(_))
        || matches!(v, serde_json::Value::Array(items) if items.iter().all(|i| i.is_string()))
}

Type guard

fn is_valid_filter_value(v: &serde_json::Value) -> bool {
    matches!(v, serde_json::Value::String(_))
        || matches!(v, serde_json::Value::Array(items) if items.iter().all(|i| i.is_string()))
}

Try / catch

for (key, value) in &config.filters {
    if !is_valid_filter_value(value) {
        anyhow::bail!("filter {key:?} must be a string or array of strings (got {value})");
    }
}

Prevention

When it happens

Trigger: Config such as {"filter_symbols": 123}, {"filter_currencies": true} or an inline YAML mapping where a scalar was intended but no quotes were used, so the value parses as a non-string JSON type.

Common situations: YAML with unquoted values that look like numbers/booleans; config generated by templating that drops quotes; copy-paste from docs rendering values without quotes.

Related errors


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