{"record":{"id":"a19d15a327f7c2b8","repo":"nautechsystems/nautilus_trader","slug":"account-account-id-not-found-after-cache-update","errorCode":null,"errorMessage":"Account {account_id} not found after cache update","messagePattern":"Account (.+?) not found after cache update","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/cache/mod.rs","lineNumber":5232,"sourceCode":"            Some(account_cell) => *account_cell.borrow_mut() = account,\n            None => {\n                self.accounts.insert(account_id, SharedCell::new(account));\n            }\n        }\n    }\n\n    /// Updates the `account` in the cache, taking ownership of the updated account.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if updating the account in the database fails.\n    pub fn update_account_owned(&mut self, account: AccountAny) -> anyhow::Result<()> {\n        let account_id = account.id();\n        self.cache_account_owned(account);\n\n        if let Some(database) = &mut self.database {\n            let Some(account_cell) = self.accounts.get(&account_id) else {\n                anyhow::bail!(\"Account {account_id} not found after cache update\");\n            };\n            database.update_account(&account_cell.borrow())?;\n        }\n        Ok(())\n    }\n\n    /// Applies an account state event to the cached account.\n    ///\n    /// Mutates the cached account in place to avoid cloning the account event\n    /// history on the hot path; long-running sessions accumulate many events\n    /// per account, so a snapshot-clone here would be O(history) per update.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if applying or persisting the account state fails.\n    pub fn update_account_state(&mut self, event: &AccountState) -> anyhow::Result<()> {\n        let Some(cell) = self.accounts.get(&event.account_id) else {\n            return self.add_account(AccountAny::from_events(std::slice::from_ref(event))?);","sourceCodeStart":5214,"sourceCodeEnd":5250,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/cache/mod.rs#L5214-L5250","documentation":"`update_account_owned` writes the account into the in-memory cache, then needs it (as a shared cell) to persist to the backing database. If the account cannot be found in `self.accounts` immediately after `cache_account_owned`, an internal invariant was violated (the cache-upsert failed to store it), so the update aborts before touching the database.","triggerScenarios":"Calling `update_account_owned` when `cache_account_owned` failed to insert the account (e.g. an account with a colliding or malformed AccountId, or corrupted cache state); a database-backed cache whose account map was cleared concurrently by another owner.","commonSituations":"Persistent (backed) caches where an account was removed between the write and the read; custom account types whose `id()` collides or changes; bespoke code paths inserting accounts without going through the cache.","solutions":["Ensure the account is added via the supported `add_account`/`update_account` path so `cache_account_owned` succeeds.","Verify the account's AccountId is stable and unique; do not mutate it after construction.","Rebuild/reload the cache if its internal state was cleared concurrently; check for multi-owner access to the cache."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if cache.account(&account_id).is_none() {\n    // add the account via the supported path before update_account_owned\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = cache.update_account_owned(account) {\n    // treat as internal invariant violation: log state, consider cache reload\n}","preventionTips":["Add accounts only through the supported cache APIs.","Never mutate an AccountId after construction.","Avoid sharing one Cache across owners that can clear state concurrently."],"tags":["rust","cache","account","internal-invariant","database"],"backgroundTag":"internal-invariant-violation","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"}