{"record":{"id":"b1f1bd6c5623f01d","repo":"nautechsystems/nautilus_trader","slug":"position-position-id-not-found","errorCode":null,"errorMessage":"Position {position_id} not found","messagePattern":"Position (.+?) not found","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/cache/mod.rs","lineNumber":5938,"sourceCode":"    /// Each [`PositionRef`] in the returned vector borrows its underlying cell; mutating any of\n    /// those positions while the vector is alive will panic at runtime. Drop the vector before\n    /// issuing writes.\n    ///\n    /// # Panics\n    ///\n    /// Panics if any `position_id` in the set is not found in the cache.\n    fn get_positions_for_ids(\n        &self,\n        position_ids: &AHashSet<PositionId>,\n        side: Option<PositionSide>,\n    ) -> Vec<PositionRef<'_>> {\n        let mut positions = Vec::new();\n\n        for position_id in position_ids {\n            let position_cell = self\n                .positions\n                .get(position_id)\n                .unwrap_or_else(|| panic!(\"Position {position_id} not found\"));\n            let position = PositionRef::new(position_cell.borrow());\n\n            if side.is_none_or(|side| side == position.side) {\n                positions.push(position);\n            }\n        }\n\n        // Sort so callers receive a deterministic Vec across runs; the\n        // underlying position_ids set is AHash-backed.\n        positions.sort_by_key(|p| p.id);\n        positions\n    }\n\n    /// Returns the `ClientOrderId`s of all orders.\n    #[must_use]\n    pub fn client_order_ids(\n        &self,\n        venue: Option<&Venue>,","sourceCodeStart":5920,"sourceCodeEnd":5956,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/cache/mod.rs#L5920-L5956","documentation":"This panic fires in the cache's bulk position fetch: each position_id in position_ids must exist in self.positions or the code panics via unwrap_or_else. It assumes callers pass only ids of open or retained positions, so a missing id is an invariant violation.","triggerScenarios":"Calling the bulk position accessor with a position_id that was never opened, was closed and purged from the cache, or comes from another backtest/session.","commonSituations":"Holding position ids from a previous run or report while running a fresh backtest; flat/closed positions removed from the cache but still referenced by strategy state; id typos.","solutions":["Verify each position_id belongs to the current run and still exists in the cache","Filter the id list against cache presence before the bulk fetch","Avoid retaining position ids across cache resets; re-query open positions instead","Log the missing position_id and cross-check with the originating source"],"exampleFix":"// before\nlet positions = cache.positions(&stale_position_ids, None);\n// after\nlet ids: Vec<PositionId> = stale_position_ids\n    .into_iter()\n    .filter(|pid| cache.position(pid).is_some())\n    .collect();\nlet positions = cache.positions(&ids, None);","handlingStrategy":"validation","validationCode":"let known: Vec<&PositionId> = position_ids\n    .iter()\n    .filter(|pid| cache.position(pid).is_some())\n    .collect();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Re-derive open position ids from the cache instead of caching them in strategy state","Filter against cache presence before bulk fetch","Clear stored position ids when the cache is reset between runs"],"tags":["rust","cache","panic","position-not-found"],"backgroundTag":"record-not-found","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"}