{"record":{"id":"851ffed9438a9200","repo":"nautechsystems/nautilus_trader","slug":"missing-field-field-in-filter","errorCode":null,"errorMessage":"Missing field '{field}' in filter","messagePattern":"Missing field '(.+?)' in filter","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/parse.rs","lineNumber":153,"sourceCode":"    Currency::get_or_create_crypto(code)\n}\n\n/// Extracts filter values from Binance symbol filters array.\nfn get_filter<'a>(filters: &'a [Value], filter_type: &str) -> Option<&'a Value> {\n    filters.iter().find(|f| {\n        f.get(\"filterType\")\n            .and_then(|v| v.as_str())\n            .is_some_and(|t| t == filter_type)\n    })\n}\n\n/// Parses a string field from a JSON value.\nfn parse_filter_string(filter: &Value, field: &str) -> anyhow::Result<String> {\n    filter\n        .get(field)\n        .and_then(|v| v.as_str())\n        .map(String::from)\n        .ok_or_else(|| anyhow::anyhow!(\"Missing field '{field}' in filter\"))\n}\n\n/// Parses a Price from a filter field.\nfn parse_filter_price(filter: &Value, field: &str) -> anyhow::Result<Price> {\n    let value = parse_filter_string(filter, field)?;\n    Price::from_str(&value).map_err(|e| anyhow::anyhow!(\"Failed to parse {field}='{value}': {e}\"))\n}\n\n/// Parses a Quantity from a filter field.\nfn parse_filter_quantity(filter: &Value, field: &str) -> anyhow::Result<Quantity> {\n    let value = parse_filter_string(filter, field)?;\n    Quantity::from_str(&value)\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse {field}='{value}': {e}\"))\n}\n\n/// Parses the futures `MIN_NOTIONAL` filter into a `Money` value in `currency`.\n///\n/// Returns `None` when the filter is absent, the `notional` field cannot be","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/common/parse.rs#L135-L171","documentation":"While extracting parameters from a Binance exchangeInfo filter object (PRICE_FILTER, LOT_SIZE, MIN_NOTIONAL, ...), the expected string field named in the message (tickSize, stepSize, notional, ...) is absent or not a string. The filter JSON does not match the schema the parser expects.","triggerScenarios":"Binance changes or extends a filter's field set, introduces a new filter type reusing known filterType tags with different fields, or an intermediate proxy/gateway mangles the exchangeInfo response.","commonSituations":"Adapter version older than a live exchangeInfo schema change; custom API gateways rewriting responses; replayed captures from a schema transition period.","solutions":["Update the Binance adapter to the latest release tracking the current exchangeInfo schema","Capture the raw exchangeInfo response, confirm which filter lacks the field, and report it to maintainers","Bypass any proxy/gateway that rewrites instrument responses while loading instruments"],"exampleFix":"// before: assuming the field always exists\nlet tick = parse_filter_string(&filter, \"tickSize\")?;\n\n// after: tolerate schema drift explicitly\nlet tick = parse_filter_string(&filter, \"tickSize\")\n    .with_context(|| format!(\"filter schema drift: {filter:?}\"))?;","handlingStrategy":"validation","validationCode":"fn filter_has_string_field(filter: &serde_json::Value, field: &str) -> bool {\n    filter.get(field).is_some_and(|v| v.is_string())\n}\n// check required fields per filter type before parsing, e.g. PRICE_FILTER: tickSize/minPrice/maxPrice","typeGuard":"fn is_wellformed_price_filter(f: &serde_json::Value) -> bool {\n    [\"tickSize\", \"minPrice\", \"maxPrice\"].iter().all(|k| f.get(k).is_some_and(|v| v.is_string()))\n}","tryCatchPattern":"let tick = parse_filter_string(&filter, \"tickSize\")\n    .with_context(|| format!(\"unexpected exchangeInfo filter schema: {filter:?}\"))?;","preventionTips":["Pin adapter versions and upgrade promptly when Binance announces exchangeInfo changes","Log the full raw filter object on parse failure so schema drift is immediately visible","Avoid proxies that reshape exchange metadata responses"],"tags":["binance","exchange-info","filters","schema","instrument-parsing"],"backgroundTag":"schema-validation-failed","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}