{"record":{"id":"e0dc170d870a2315","repo":"nautechsystems/nautilus_trader","slug":"cannot-apply-betting-account-state-balance-would","errorCode":null,"errorMessage":"Cannot apply betting account state: balance would be negative {} {} ({})","messagePattern":"Cannot apply betting account state: balance would be negative (.+?) (.+?) \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/accounts/betting.rs","lineNumber":177,"sourceCode":"}\n\nimpl Account for BettingAccount {\n    impl_account_base_members!();\n\n    fn is_cash_account(&self) -> bool {\n        true\n    }\n\n    fn is_margin_account(&self) -> bool {\n        false\n    }\n\n    fn apply(&mut self, event: AccountState) -> anyhow::Result<()> {\n        self.check_event_account_id(&event)?;\n\n        for balance in &event.balances {\n            if balance.total.raw < 0 {\n                anyhow::bail!(\n                    \"Cannot apply betting account state: balance would be negative {} {} ({})\",\n                    balance.total.as_decimal(),\n                    balance.currency.code,\n                    self.id\n                );\n            }\n        }\n\n        if event.is_reported {\n            self.balances_locked.clear();\n        }\n\n        self.base_apply(event);\n        Ok(())\n    }\n\n    fn calculate_balance_locked(\n        &self,","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/accounts/betting.rs#L159-L195","documentation":"BettingAccountState::apply rejects an AccountState event whose balance total is negative, because a betting account cannot hold a negative balance. The library bails with anyhow::Error naming the total, currency, and account id. It guards against corrupt or miscomputed account event data.","triggerScenarios":"Calling apply() (or py_apply / betting_account_from_account_events) with an AccountState whose event.balances contains any balance with total.raw < 0.","commonSituations":"Feeding incorrectly signed balance data from a backtest fill model, converting balances from a broker export with wrong signs, or constructing AccountState events by hand with negative totals.","solutions":["Inspect the AccountState event balances and correct the negative total values at the source before applying","If the negative balance is legitimate, use a cash/margin account with allow_borrowing instead of a betting account","Verify upstream balance computation (deposits/withdrawals/adjustments) for sign errors"],"exampleFix":"// before: event with negative total\nlet mut state = AccountState::new(...);\nstate.balances = vec![AccountBalance::new(Money::from(-100.0, AUD), ...)];\naccount.apply(state)?; // bails\n// after: ensure non-negative total\nassert!(total.as_decimal() >= Decimal::ZERO);\naccount.apply(state)?;","handlingStrategy":"validation","validationCode":"if event.balances.iter().any(|b| b.total.raw < 0) { return Err(anyhow!(\"event has negative balance\")); }\naccount.apply(event)?;","typeGuard":"fn has_non_negative_balances(event: &AccountState) -> bool {\n    event.balances.iter().all(|b| b.total.raw >= 0)\n}","tryCatchPattern":"match account.apply(event) {\n    Err(e) if e.to_string().contains(\"balance would be negative\") => { /* fix event data */ }\n    other => other?,\n}","preventionTips":["Check balance signs when building AccountState events","Never reuse margin/cash event data for betting accounts","Add unit tests asserting non-negative totals for generated events"],"tags":["rust","accounts","validation","balance"],"backgroundTag":"invalid-state-transition","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"}