{"record":{"id":"7db8da75717b999b","repo":"nautechsystems/nautilus_trader","slug":"cannot-apply-account-state-balance-would-be-negat","errorCode":null,"errorMessage":"Cannot apply account state: balance would be negative {} {} (borrowing not allowed for {})","messagePattern":"Cannot apply account state: balance would be negative (.+?) (.+?) \\(borrowing not allowed for (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/accounts/cash.rs","lineNumber":190,"sourceCode":"\nimpl Account for CashAccount {\n    impl_account_base_members!();\n\n    fn is_cash_account(&self) -> bool {\n        self.account_type == AccountType::Cash\n    }\n\n    fn is_margin_account(&self) -> bool {\n        self.account_type == AccountType::Margin\n    }\n\n    fn apply(&mut self, event: AccountState) -> anyhow::Result<()> {\n        self.check_event_account_id(&event)?;\n\n        if !self.allow_borrowing {\n            for balance in &event.balances {\n                if balance.total.raw < 0 {\n                    anyhow::bail!(\n                        \"Cannot apply account state: balance would be negative {} {} \\\n                        (borrowing not allowed for {})\",\n                        balance.total.as_decimal(),\n                        balance.currency.code,\n                        self.id\n                    );\n                }\n            }\n        }\n\n        // Only clear locks when the venue reports a fresh balance snapshot\n        if event.is_reported && !event.balances.is_empty() {\n            self.balances_locked.clear();\n        }\n\n        self.base_apply(event);\n        Ok(())\n    }","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/accounts/cash.rs#L172-L208","documentation":"CashAccount::apply validates AccountState events the same way update_balances does: when allow_borrowing is false, any balance with a negative total causes the event application to fail. This keeps account state consistent with the no-borrowing constraint.","triggerScenarios":"Calling apply() (or py_apply) with an AccountState event containing a negative balance total while the CashAccount has allow_borrowing=false.","commonSituations":"Replaying account state events generated under different account config (borrowing later disabled), restoring snapshots that include overdrafts, wiring events from a margin context into a cash account.","solutions":["Re-generate or clamp the AccountState balances to non-negative values","Create the CashAccount with allow_borrowing=true if negative totals are legitimate","Check that events are being routed to the correct account type"],"exampleFix":"// before: applying event to non-borrowing account\nif !allow_borrowing { /* negative totals bail */ }\n// after: guard before applying\nlet ok = event.balances.iter().all(|b| b.total.raw >= 0 || allow_borrowing);\nanyhow::ensure!(ok, \"negative balance with borrowing disabled\");\naccount.apply(event)?;","handlingStrategy":"validation","validationCode":"if !acct.allows_borrowing() && event.balances.iter().any(|b| b.total.raw < 0) { return Err(anyhow!(\"negative balance event\")); }\nacct.apply(event)?;","typeGuard":"fn event_appliable(acct: &CashAccount, event: &AccountState) -> bool {\n    acct.allows_borrowing() || event.balances.iter().all(|b| b.total.raw >= 0)\n}","tryCatchPattern":"if let Err(e) = acct.apply(event) {\n    if e.to_string().contains(\"borrowing not allowed\") { /* regenerate event or enable borrowing */ }\n}","preventionTips":["Keep account config consistent across event generation and replay","Verify event sources target the correct account type","Snapshot/restore flows should validate balances before apply"],"tags":["rust","accounts","cash","balance","borrowing"],"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"}