{"record":{"id":"6e542c311dbe223a","repo":"nautechsystems/nautilus_trader","slug":"failed-to-load-custom-data-e","errorCode":null,"errorMessage":"Failed to load custom data: {e}","messagePattern":"Failed to load custom data: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/infrastructure/src/sql/queries.rs","lineNumber":1722,"sourceCode":"                .fetch_all(pool)\n                .await\n            }\n            None => {\n                sqlx::query(\n                    r#\"SELECT value, ts_event, ts_init FROM \"custom\"\n                   WHERE (data_type = $1 OR data_type = $2)\n                     AND metadata = $3\n                     AND identifier = ''\n                   ORDER BY ts_init ASC\"#,\n                )\n                .bind(type_name)\n                .bind(short_type)\n                .bind(&metadata_json)\n                .fetch_all(pool)\n                .await\n            }\n        }\n        .map_err(|e| anyhow::anyhow!(\"Failed to load custom data: {e}\"))?;\n\n        let mut results = Vec::with_capacity(rows.len());\n        for row in rows {\n            let value_json: serde_json::Value = row.try_get(\"value\")?;\n            let json_bytes = serde_json::to_vec(&value_json)\n                .map_err(|e| anyhow::anyhow!(\"Failed to serialize JSON: {e}\"))?;\n            let custom =\n                CustomData::from_json_bytes(&json_bytes).map_err(|e| anyhow::anyhow!(\"{e}\"))?;\n            results.push(custom);\n        }\n        Ok(results)\n    }\n}\n","sourceCodeStart":1704,"sourceCodeEnd":1736,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/infrastructure/src/sql/queries.rs#L1704-L1736","documentation":"Raised by `load_custom_data` when the SELECT used to fetch `custom` rows for the requested data type fails. The query builder has several branches (with/without metadata and identifier filters); any sqlx fetch failure across them is wrapped with this message.","triggerScenarios":"Calling `load_custom_data(pool, data_type, ...)` when the `custom` table is missing, the metadata_json binding is malformed for the comparison used, the pool connection fails, or schema columns don't match the query.","commonSituations":"Migrations not applied; passing metadata that doesn't match the JSONB column format expected by the query; wrong database; transient PostgreSQL restarts.","solutions":["Inspect the wrapped sqlx error message for the exact failure.","Run migrations so the `custom` table exists with value/data_type/metadata/identifier columns.","Ensure the metadata argument matches the JSON format stored when inserting (serde_json string).","Retry transient failures; validate pool connectivity."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"let exists: bool = sqlx::query_scalar(\n    \"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'custom')\")\n    .fetch_one(pool).await?;\nanyhow::ensure!(exists, \"custom table missing; run migrations\");\n// metadata must be a valid JSON string matching stored format\nif let Some(m) = &metadata { serde_json::from_str::<serde_json::Value>(m)?; }","typeGuard":null,"tryCatchPattern":"let rows = retry_backoff(3, || load_custom_data(&pool, data_type.clone(), metadata.clone(), identifier.clone())).await\n    .map_err(|e| e.context(\"custom data load failed after retries\"))?;","preventionTips":["Store metadata exactly as the API expects (serialized JSON string)","Apply migrations before querying","Use bounded retries for transient failures","Verify data_type naming matches what was inserted"],"tags":["database","sqlx","query"],"backgroundTag":"sql-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"}