{"record":{"id":"ece68b5571c371f5","repo":"nautechsystems/nautilus_trader","slug":"failed-to-load-instrument-closes-e","errorCode":null,"errorMessage":"Failed to load instrument closes: {e}","messagePattern":"Failed to load instrument closes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/queries.rs","lineNumber":286,"sourceCode":"        .execute(pool)\n        .await\n        .map(|_| ())\n        .map_err(|e| anyhow::anyhow!(\"Failed to insert instrument close: {e}\"))\n    }\n\n    /// Loads all `InstrumentClose` entries.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the SQL SELECT or row decoding fails.\n    pub async fn load_instrument_closes(pool: &PgPool) -> anyhow::Result<Vec<InstrumentClose>> {\n        sqlx::query_as::<_, InstrumentCloseRow>(\n            \"SELECT * FROM instrument_close ORDER BY instrument_id ASC\",\n        )\n        .fetch_all(pool)\n        .await\n        .map(|rows| rows.into_iter().map(|row| row.0).collect())\n        .map_err(|e| anyhow::anyhow!(\"Failed to load instrument closes: {e}\"))\n    }\n\n    /// Inserts an `OrderInitialized` event via the provided `pool`.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the SQL INSERT or UPDATE operation fails.\n    pub async fn add_order(\n        pool: &PgPool,\n        event: OrderInitialized,\n        client_id: Option<ClientId>,\n    ) -> anyhow::Result<()> {\n        Self::add_order_event(pool, Box::new(event), client_id).await\n    }\n\n    /// Inserts an `OrderSnapshot` entry via the provided `pool`.\n    ///\n    /// # Errors","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/queries.rs#L268-L304","documentation":"Raised by `load_instrument_closes` when the ordered `SELECT * FROM instrument_close` query fails. The sqlx error from `fetch_all` is wrapped in `anyhow` with this message. The caller receives no instrument close history, which typically breaks replay or analysis that depends on close records.","triggerScenarios":"Calling `load_instrument_closes(&pool)` when: the `instrument_close` table is missing (migrations not run); the connection is broken or the pool has no connections; a row's column types fail to decode into `InstrumentCloseRow`; or the query is cancelled/times out.","commonSituations":"Pointing at a fresh database without schema; schema drift after a crate upgrade changing `InstrumentCloseRow` fields; database restart mid-session leaving stale pooled connections; large table causing statement timeout.","solutions":["Read the wrapped `{e}` text to distinguish connection, schema, and decode failures.","Run the required migrations so `instrument_close` exists.","Check database connectivity and enable pool health checks / reconnection.","If decoding fails, align table column types with `InstrumentCloseRow` (schema or crate version mismatch)."],"exampleFix":"// before\nlet closes = load_instrument_closes(&pool).await?;\n\n// after: retry transient failures\nlet closes = loop {\n    match load_instrument_closes(&pool).await {\n        Ok(c) => break c,\n        Err(e) if is_transient(&format!(\"{e:#}\")) => {\n            tokio::time::sleep(std::time::Duration::from_secs(1)).await;\n        }\n        Err(e) => return Err(e),\n    }\n};","handlingStrategy":"retry","validationCode":"let ok = sqlx::query_scalar::<_, i64>(\n    \"SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 'instrument_close'\")\n    .fetch_one(pool).await? > 0;\nif !ok { return Err(anyhow::anyhow!(\"instrument_close table missing: run migrations\")); }","typeGuard":null,"tryCatchPattern":"async fn load_closes_with_retry(pool: &PgPool) -> anyhow::Result<Vec<InstrumentClose>> {\n    let mut delay = std::time::Duration::from_millis(250);\n    loop {\n        match load_instrument_closes(pool).await {\n            Ok(v) => return Ok(v),\n            Err(e) => {\n                if !is_transient(&format!(\"{e:#}\")) { return Err(e); }\n                tokio::time::sleep(delay).await;\n                delay *= 2;\n            }\n        }\n    }\n}","preventionTips":["Use PgPoolOptions with `after_connect`/acquire-timeout health checks.","Set a statement timeout appropriate for the table size.","Re-run migrations after every crate upgrade that changes row structs.","Log the full error chain (`{e:#}`) to capture the underlying sqlx cause."],"tags":["database","postgres","sqlx","rust","select"],"backgroundTag":"database-query-failed","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"}