{"record":{"id":"df1a7898f2bb7e63","repo":"nautechsystems/nautilus_trader","slug":"binance-instrument-filter-name-must-be-a-non-e","errorCode":null,"errorMessage":"Binance instrument filter {name:?} must be a non-empty string or array of strings","messagePattern":"Binance instrument filter (.+?) must be a non-empty string or array of strings","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/config.rs","lineNumber":138,"sourceCode":"        }\n\n        Ok(())\n    }\n}\n\nfn validate_filter_strings(name: &str, value: &serde_json::Value) -> anyhow::Result<()> {\n    let valid = match value {\n        serde_json::Value::String(value) => !value.trim().is_empty(),\n        serde_json::Value::Array(values) => {\n            !values.is_empty()\n                && values\n                    .iter()\n                    .all(|value| value.as_str().is_some_and(|value| !value.trim().is_empty()))\n        }\n        _ => false,\n    };\n\n    anyhow::ensure!(\n        valid,\n        \"Binance instrument filter {name:?} must be a non-empty string or array of strings\"\n    );\n    Ok(())\n}\n\n/// Spot market-data transport mode.\n#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]\n#[cfg_attr(\n    feature = \"python\",\n    pyo3::pyclass(module = \"nautilus_trader.adapters.binance\", eq, from_py_object)\n)]\n#[cfg_attr(\n    feature = \"python\",\n    pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = \"nautilus_trader.adapters.binance\")\n)]\npub enum BinanceSpotMarketDataMode {\n    #[default]","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/config.rs#L120-L156","documentation":"Each Binance instrument provider filter value must be either a non-empty string or a non-empty array of non-empty strings. validate_filter_strings() rejects values of any other JSON type (number, bool, object, null) or empty/whitespace-only strings. This ensures filter values serialize into valid REST query parameters.","triggerScenarios":"Setting an instrument filter value to an empty string (\"\"), an empty array ([]), a non-string type (number/bool/object), or an array containing empty strings, then calling validate().","commonSituations":"Environment-variable-driven config where an optional filter resolves to an empty string; deserialized JSON where the filter value was a number; building filters programmatically with an uninitialized empty list.","solutions":["Provide a non-empty string value for the filter, e.g. symbols=\"BTCUSDT\".","Provide a non-empty array of non-empty strings, e.g. symbols=[\"BTCUSDT\",\"ETHUSDT\"] with all entries trimmed non-empty.","Remove the filter entirely if you do not intend to filter.","Trim and check user-supplied filter values before constructing the config."],"exampleFix":"// before\nfilters.insert(\"symbols\", json!([]));\n// after\nfilters.insert(\"symbols\", json!([\"BTCUSDT\", \"ETHUSDT\"]));","handlingStrategy":"validation","validationCode":"fn filter_value_ok(v: &serde_json::Value) -> bool {\n    match v {\n        serde_json::Value::String(s) => !s.trim().is_empty(),\n        serde_json::Value::Array(a) => {\n            !a.is_empty()\n                && a.iter().all(|x| x.as_str().is_some_and(|s| !s.trim().is_empty()))\n        }\n        _ => false,\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never insert empty strings or empty arrays as filter values; omit the filter instead.","Normalize/trim values loaded from env vars before building filters.","Store symbol lists as Vec<String> in your own config and serialize only when non-empty."],"tags":["config","validation","binance","empty-value"],"backgroundTag":"empty-required-field","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}