{"record":{"id":"4f0788f058a0e893","repo":"nautechsystems/nautilus_trader","slug":"filter-key-is-not-a-string-or-array","errorCode":null,"errorMessage":"filter {key:?} is not a string or array","messagePattern":"filter (.+?) is not a string or array","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/instruments.rs","lineNumber":103,"sourceCode":"fn filter_values(\n    config: &BinanceInstrumentProviderConfig,\n    key: &str,\n) -> anyhow::Result<Option<AHashSet<String>>> {\n    let Some(value) = config.filters.get(key) else {\n        return Ok(None);\n    };\n\n    let values = match value {\n        serde_json::Value::String(value) => vec![value.as_str()],\n        serde_json::Value::Array(values) => values\n            .iter()\n            .map(|value| {\n                value\n                    .as_str()\n                    .ok_or_else(|| anyhow::anyhow!(\"filter {key:?} contains a non-string value\"))\n            })\n            .collect::<anyhow::Result<Vec<_>>>()?,\n        _ => anyhow::bail!(\"filter {key:?} is not a string or array\"),\n    };\n\n    Ok(Some(\n        values\n            .into_iter()\n            .map(|value| value.trim().to_ascii_uppercase())\n            .collect(),\n    ))\n}\n\nfn matches_filter(values: &Option<AHashSet<String>>, value: &str) -> bool {\n    values.as_ref().is_none_or(|values| contains(values, value))\n}\n\nfn contains(values: &AHashSet<String>, value: &str) -> bool {\n    values.contains(&value.to_ascii_uppercase())\n}\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/common/instruments.rs#L85-L121","documentation":"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.","triggerScenarios":"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.","commonSituations":"YAML with unquoted values that look like numbers/booleans; config generated by templating that drops quotes; copy-paste from docs rendering values without quotes.","solutions":["Wrap the value in quotes (single string form) or make it an array of quoted strings","Re-check every filter key in the client config for correct JSON/YAML typing","Add a config schema check before client construction"],"exampleFix":"# before (YAML)\nfilter_symbols: 1234      # parses as integer\n\n# after\nfilter_symbols: \"1234\"    # or [\"1234\", \"5678\"]","handlingStrategy":"validation","validationCode":"fn filter_key_valid(v: &serde_json::Value) -> bool {\n    matches!(v, serde_json::Value::String(_))\n        || matches!(v, serde_json::Value::Array(items) if items.iter().all(|i| i.is_string()))\n}","typeGuard":"fn is_valid_filter_value(v: &serde_json::Value) -> bool {\n    matches!(v, serde_json::Value::String(_))\n        || matches!(v, serde_json::Value::Array(items) if items.iter().all(|i| i.is_string()))\n}","tryCatchPattern":"for (key, value) in &config.filters {\n    if !is_valid_filter_value(value) {\n        anyhow::bail!(\"filter {key:?} must be a string or array of strings (got {value})\");\n    }\n}","preventionTips":["Quote scalar filter values in YAML, or always use the array form with quoted entries","Lint venue configs in CI with the same string-or-string-array rule","Prefer structured config types over free-form maps"],"tags":["binance","configuration","json-parsing","instrument-filters","yaml"],"backgroundTag":"config-validation-failed","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}