{"record":{"id":"eea2d742ffb35dcd","repo":"nautechsystems/nautilus_trader","slug":"failed-to-send-query-index-order-position-to-datab","errorCode":null,"errorMessage":"Failed to send query index_order_position to database message handler: {e}","messagePattern":"Failed to send query index_order_position to database message handler: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/cache.rs","lineNumber":1230,"sourceCode":"        Ok(rx.recv()?)\n    }\n\n    fn index_venue_order_id(\n        &self,\n        _client_order_id: ClientOrderId,\n        _venue_order_id: VenueOrderId,\n    ) -> anyhow::Result<()> {\n        todo!()\n    }\n\n    fn index_order_position(\n        &self,\n        client_order_id: ClientOrderId,\n        position_id: PositionId,\n    ) -> anyhow::Result<()> {\n        let query = DatabaseQuery::IndexOrderPosition(client_order_id, position_id);\n        self.tx.send(query).map_err(|e| {\n            anyhow::anyhow!(\n                \"Failed to send query index_order_position to database message handler: {e}\"\n            )\n        })\n    }\n\n    fn index_order_clients(&self, claims: &[(ClientOrderId, ClientId)]) -> anyhow::Result<()> {\n        if claims.is_empty() {\n            return Ok(());\n        }\n\n        let query = DatabaseQuery::IndexOrderClients(claims.to_vec());\n        self.tx.send(query).map_err(|e| {\n            anyhow::anyhow!(\n                \"Failed to send query index_order_clients to database message handler: {e}\"\n            )\n        })\n    }\n","sourceCodeStart":1212,"sourceCodeEnd":1248,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/cache.rs#L1212-L1248","documentation":"index_order_position sends DatabaseQuery::IndexOrderPosition (a ClientOrderId→PositionId mapping) over the cache's mpsc channel to the database message handler; send failure becomes this error. The send can only fail if the handler's receiver was dropped, meaning the background persistence task is gone. No lookup or write has happened yet — the index command never reached the database layer.","triggerScenarios":"Calling index_order_position when the handler task has exited (adapter shutdown, aborted task, handler died at init), typically while an execution engine still indexes order/position links.","commonSituations":"Cache adapter torn down while a trading node keeps running; handler panicked earlier leaving the channel closed; reusing an adapter from a previous async runtime context.","solutions":["Ensure the database adapter and handler task are running before indexing operations","Recreate the adapter after shutdown rather than writing through stale handles","Investigate the handler's exit reason in logs and fix the root cause","Fail fast on this error in execution paths — an unindexed order/position link can break position reporting"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = cache.index_order_position(&client_order_id, &position_id) {\n    // channel to DB handler is closed — persistence layer is down\n    tracing::error!(\"order-position indexing failed: {e:#}\");\n    return Err(e.into());\n}","preventionTips":["Fail fast: indexing is critical for position reporting, do not swallow the error","Maintain strict shutdown ordering between execution engine and cache","Verify adapter startup health before the engine begins indexing","Alert on any handler task exit in live deployments"],"tags":["rust","channel","database","postgres"],"backgroundTag":"broken-pipe","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"}