{"record":{"id":"7adfdec707a47c91","repo":"nautechsystems/nautilus_trader","slug":"wallet-has-no-observed-balance-for","errorCode":null,"errorMessage":"wallet has no observed balance for {}","messagePattern":"wallet has no observed balance for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/accounts/wallet.rs","lineNumber":140,"sourceCode":"\n    /// Updates the locked balance for the given instrument and currency.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if `locked` is negative, the wallet has no observed balance for its\n    /// currency, or the local reservations cannot produce a valid balance.\n    pub fn update_balance_locked(\n        &mut self,\n        instrument_id: InstrumentId,\n        locked: Money,\n    ) -> anyhow::Result<()> {\n        let current_balance = self\n            .base\n            .balances\n            .get(&locked.currency)\n            .copied()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\"wallet has no observed balance for {}\", locked.currency)\n            })?;\n        Self::validate_observed_balance(current_balance)?;\n        let locked = Self::normalize_reservation(locked, current_balance.currency)?;\n        let key = (instrument_id, current_balance.currency);\n        let previous = self.balances_locked.remove_entry(&key);\n        self.balances_locked.insert(key, locked);\n        let balance = match Self::balance_from_locks_checked(current_balance, &self.balances_locked)\n        {\n            Ok(balance) => balance,\n            Err(e) => {\n                self.balances_locked.remove(&key);\n                if let Some((previous_key, previous)) = previous {\n                    self.balances_locked.insert(previous_key, previous);\n                }\n\n                return Err(e.into());\n            }\n        };","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/accounts/wallet.rs#L122-L158","documentation":"update_balance_locked reserves balance for an instrument but requires that the wallet has already observed a balance in the reservation's currency. If self.base.balances has no entry for that currency, the reservation cannot be validated or normalized and this error is thrown. It enforces the invariant that locks apply only to currencies the wallet actually holds.","triggerScenarios":"Calling AccountWallet::update_balance_locked (directly or via apply of an event) with a AccountBalanceLocked whose currency was never reported via a balance update — e.g. locking funds in a currency before any balance event arrived.","commonSituations":"Submitting orders in a quote/base currency the wallet has not received a balance snapshot for; race at startup where order flow precedes the initial balance event; adapter not emitting balances for all currencies.","solutions":["Ensure an initial balance update for the currency is applied to the wallet before locking","Check self.balances contains the currency before calling update_balance_locked","Fix event ordering so balance events are processed before order-related locks"],"exampleFix":"// before\nwallet.update_balance_locked(instrument_id, locked).unwrap();\n// after\nif !wallet.balances().contains_key(&locked.currency) {\n    anyhow::bail!(\"no observed balance for {} yet\", locked.currency);\n}\nwallet.update_balance_locked(instrument_id, locked)?;","handlingStrategy":"validation","validationCode":"if wallet.balances().get(&locked.currency).is_none() {\n    bail!(\"cannot lock {}: no observed balance\", locked.currency);\n}","typeGuard":"fn has_observed_balance(wallet: &AccountWallet, c: &Currency) -> bool {\n    wallet.balances().contains_key(c)\n}","tryCatchPattern":"match wallet.update_balance_locked(instrument_id, locked) {\n    Ok(()) => ...,\n    Err(e) if e.to_string().contains(\"no observed balance\") => warn!(\"balance not yet observed, deferring lock\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Apply initial balance snapshots before processing order events","Ensure adapters emit balances for all traded currencies","Enforce event ordering: balance events before order locks"],"tags":["rust","wallet","balance","state"],"backgroundTag":"resource-not-found","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}