{"record":{"id":"19f79897e72e8251","repo":"nautechsystems/nautilus_trader","slug":"failed-to-advance-balances-group-e","errorCode":null,"errorMessage":"Failed to advance balances group: {e:?}","messagePattern":"Failed to advance balances group: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/spot/websocket/trading/decode_sbe.rs","lineNumber":295,"sourceCode":"        anyhow::bail!(\n            \"Buffer too short for fixed block: expected {min_len}, was {}\",\n            data.len()\n        );\n    }\n\n    let dec = outbound_account_position_event_codec::OutboundAccountPositionEventDecoder::default()\n        .wrap(buf, HEADER_LEN, block_length, version);\n\n    let event_time_us = dec.event_time();\n    let update_time_us = dec.update_time();\n\n    let mut balances_dec = dec.balances_decoder();\n    let count = balances_dec.count() as usize;\n    let mut balances = Vec::with_capacity(count);\n\n    while let Some(_idx) = balances_dec\n        .advance()\n        .map_err(|e| anyhow::anyhow!(\"Failed to advance balances group: {e:?}\"))?\n    {\n        let exponent = balances_dec.exponent();\n        let free_mantissa = balances_dec.free();\n        let locked_mantissa = balances_dec.locked();\n\n        let asset_coords = balances_dec.asset_decoder();\n        let asset_bytes = balances_dec.asset_slice(asset_coords);\n        let asset = Ustr::from(&String::from_utf8_lossy(asset_bytes));\n\n        balances.push(BinanceSpotBalanceEntry {\n            asset,\n            free: mantissa_to_decimal(free_mantissa, exponent),\n            locked: mantissa_to_decimal(locked_mantissa, exponent),\n        });\n    }\n\n    Ok(BinanceSpotAccountPositionMsg {\n        event_type: \"outboundAccountPosition\".to_string(),","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/spot/websocket/trading/decode_sbe.rs#L277-L313","documentation":"Decoding an SBE `ACCOUNT_POSITION` group failed while iterating the balances repeating group. `balances_dec.advance()` returned an error (malformed buffer, truncated group, or wrong template id) which is wrapped with debug formatting `{e:?}`.","triggerScenarios":"Calling `decode_account_position` on a buffer where the balances group header/entries are truncated, the message is not actually the account-position template, or the SBE block length doesn't match the schema; each `advance()` step that hits invalid data returns `Err`.","commonSituations":"Capturing frames with a mismatched SBE schema version (Binance updated the schema); cutting a frame short when recording traffic; a decoder pointed at a non-account-position message.","solutions":["Update the SBE schema and generated decoders to the current Binance version — schema drift is the most common cause.","Log and inspect the raw buffer around the balances group; compare its length against the group's `count` header.","Verify the template id before decoding (reject wrong-template messages early).","If capturing frames, ensure the full frame including the group payload is written."],"exampleFix":"// before: decoding raw captured bytes with an old generated schema\nlet msg = MessageHeaderDecoder::default().decode(buf)?; decode_account_position(&mut dec)?;\n// after: regenerate decoder bindings from the latest Binance SBE schema (sbe-tool) and rebuild","handlingStrategy":"try-catch","validationCode":"if header.template_id() != ACCOUNT_POSITION_TEMPLATE_ID {\n    return Err(anyhow::anyhow!(\"unexpected template id {}\", header.template_id()));\n}","typeGuard":null,"tryCatchPattern":"match decode_account_position(&mut dec) {\n    Ok(msg) => Ok(msg),\n    Err(e) => {\n        log::error!(\"SBE account position decode failed: {e:?}; resyncing schema/buffer\");\n        Err(e)\n    }\n}","preventionTips":["Regenerate SBE decoder bindings whenever Binance publishes a new schema version.","Validate template id and block length before group decoding.","Capture complete frames when recording traffic for replay."],"tags":["sbe","decoding","binance","protobuf-like","rust"],"backgroundTag":"schema-validation-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}