{"record":{"id":"702b293fc74c9a44","repo":"nautechsystems/nautilus_trader","slug":"invalid-ticksize-of-0","errorCode":null,"errorMessage":"Invalid tickSize of 0","messagePattern":"Invalid tickSize of 0","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/common/parse.rs","lineNumber":800,"sourceCode":"\n    let price_filter = symbol\n        .filters\n        .iter()\n        .find(|filter| filter.filter_type == \"PRICE_FILTER\")\n        .context(\"Missing PRICE_FILTER in symbol filters\")?;\n    let lot_filter = symbol\n        .filters\n        .iter()\n        .find(|filter| filter.filter_type == \"LOT_SIZE\")\n        .context(\"Missing LOT_SIZE in symbol filters\")?;\n\n    let tick_size = decimal_price(\n        price_filter\n            .tick_size\n            .as_deref()\n            .context(\"Missing PRICE_FILTER tickSize\")?,\n    )?;\n    anyhow::ensure!(!tick_size.is_zero(), \"Invalid tickSize of 0\");\n    let step_size = decimal_quantity(\n        lot_filter\n            .step_size\n            .as_deref()\n            .context(\"Missing LOT_SIZE stepSize\")?,\n    )?;\n    anyhow::ensure!(!step_size.is_zero(), \"Invalid stepSize of 0\");\n\n    let instrument = CurrencyPair::new(\n        InstrumentId::new(\n            Symbol::from_str_unchecked(&symbol.symbol),\n            Venue::new(BINANCE),\n        ),\n        Symbol::new(&symbol.symbol),\n        get_currency(&symbol.base_asset),\n        get_currency(&symbol.quote_asset),\n        tick_size.precision,\n        step_size.precision,","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/common/parse.rs#L782-L818","documentation":"While building a Spot CurrencyPair from the JSON exchangeInfo, decimal_price parses PRICE_FILTER.tickSize and the code then enforces it is non-zero. A literal \"0\" (or \"0.0\", normalized to zero) parses successfully but fails the ensure!, producing this short message.","triggerScenarios":"Spot exchangeInfo PRICE_FILTER with \"tickSize\": \"0\" for the symbol being parsed — placeholder filters on pre-listing symbols or corrupted/cached payloads.","commonSituations":"Pairs announced but not yet live; stale caches or replayed fixtures with zeroed filters; venue data glitches.","solutions":["Check the live Spot exchangeInfo tickSize for the symbol.","Skip symbols whose tickSize is zero during loading.","Refresh cached exchangeInfo data.","Report persistent zero tickSize on an actively trading pair."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"fn spot_tick_size_is_valid(symbol: &BinanceSymbolJson) -> bool {\n    symbol\n        .filters\n        .iter()\n        .find(|f| f.filter_type == \"PRICE_FILTER\")\n        .and_then(|f| f.tick_size.as_deref())\n        .map(|t| {\n            rust_decimal::Decimal::from_str(t)\n                .map(|d| !d.is_zero())\n                .unwrap_or(false)\n        })\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match parse_spot_instrument_json_with_fees(&symbol, None, None, ts_event, ts_init) {\n    Ok(inst) => instruments.push(inst),\n    Err(e) if e.to_string().contains(\"Invalid tickSize of 0\") => {\n        tracing::warn!(symbol = %symbol.symbol, \"zero tickSize, skipping\")\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Pre-check PRICE_FILTER tickSize is non-zero when filtering symbols.","Refresh cached spot exchangeInfo snapshots.","Skip pre-listing pairs until the venue fills in real filters."],"tags":["binance","spot","tick-size","price-filter","rust"],"backgroundTag":"invalid-tick-size","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}