{"record":{"id":"2bbdd127e45c54c4","repo":"nautechsystems/nautilus_trader","slug":"filter-key-contains-a-non-string-value","errorCode":null,"errorMessage":"filter {key:?} contains a non-string value","messagePattern":"filter (.+?) contains a non-string value","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/instruments.rs","lineNumber":100,"sourceCode":"    }\n}\n\nfn 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 {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/common/instruments.rs#L82-L118","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 is an array but at least one element is not a string (number, bool, null, or object).","triggerScenarios":"Config such as {\"filter_unders\": [123, \"BTCUSDT\"]} or YAML where an unquoted numeric/boolean entry parses as a non-string JSON scalar inside the filter array.","commonSituations":"YAML configs with unquoted numbers (e.g. underlying codes like 6 or 11) or booleans/nulls inside filter lists; machine-generated config from a schema-less source.","solutions":["Quote every entry in the filter array: underlyings: [\"6\", \"11\", \"BTCUSDT\"]","Ensure booleans/nulls/objects never appear in filter arrays","Validate the config JSON shape (all elements strings) before constructing the client"],"exampleFix":"# before (YAML)\nfilter_unders: [6, 11, BTCUSDT]   # 6 and 11 parse as numbers\n\n# after\nfilter_unders: [\"6\", \"11\", \"BTCUSDT\"]","handlingStrategy":"validation","validationCode":"fn filter_values_valid(v: &serde_json::Value) -> bool {\n    match v {\n        serde_json::Value::String(_) => true,\n        serde_json::Value::Array(items) => items.iter().all(|i| i.is_string()),\n        _ => false,\n    }\n}\n// run over every entry in config.filters before constructing the client","typeGuard":"fn is_string_or_string_array(v: &serde_json::Value) -> bool {\n    match v {\n        serde_json::Value::String(_) => true,\n        serde_json::Value::Array(items) => items.iter().all(|i| i.is_string()),\n        _ => false,\n    }\n}","tryCatchPattern":"if !config.filters.iter().all(|(k, v)| is_string_or_string_array(v)) {\n    anyhow::bail!(\"Binance filter config malformed - all values must be strings or arrays of strings\");\n}","preventionTips":["Quote every scalar in YAML config lists, even purely numeric codes","Validate the config JSON against a small schema before client construction","Generate config from typed structs rather than hand-editing YAML"],"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"}