nautechsystems/nautilus_trader · error
Failed to load instrument with id {instrument_id},error is:
Error message
Failed to load instrument with id {instrument_id},error is: {e} What it means
`DatabaseQueries::load_instrument` runs `SELECT * FROM instrument WHERE id = $1` and returns Ok(None) for a missing row — not-found is not an error. This anyhow error is raised only on execution failure (connectivity, missing table) or row-decoding failure, where a stored instrument row can't be converted into `InstrumentAny`, typically due to schema drift or an enum/kind value written by a different version.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:225
.map_err(|e| anyhow::anyhow!("Failed to insert item {} into instrument table: {:?}", instrument.id(), e))
}
/// Loads a single `InstrumentAny` entry by `instrument_id` via the provided `pool`.
///
/// # Errors
///
/// Returns an error if the SELECT operation fails.
pub async fn load_instrument(
pool: &PgPool,
instrument_id: &InstrumentId,
) -> anyhow::Result<Option<InstrumentAny>> {
sqlx::query_as::<_, InstrumentAnyRow>("SELECT * FROM instrument WHERE id = $1")
.bind(instrument_id.to_string())
.fetch_optional(pool)
.await
.map(|instrument| instrument.map(|row| row.0))
.map_err(|e| {
anyhow::anyhow!("Failed to load instrument with id {instrument_id},error is: {e}")
})
}
/// Loads all `InstrumentAny` entries via the provided `pool`.
///
/// # Errors
///
/// Returns an error if the SELECT operation fails.
pub async fn load_instruments(pool: &PgPool) -> anyhow::Result<Vec<InstrumentAny>> {
sqlx::query_as::<_, InstrumentAnyRow>("SELECT * FROM instrument")
.fetch_all(pool)
.await
.map(|rows| rows.into_iter().map(|row| row.0).collect())
.map_err(|e| anyhow::anyhow!("Failed to load instruments: {e}"))
}
/// Inserts or replaces an `InstrumentClose`.
///View on GitHub (pinned to 18893faf8b)
Solutions
- Run migrations matching this code version so the table and enum types decode correctly.
- Identify the undecodable row from the inner sqlx decode error; upgrade the binary or re-write the row with the current version.
- Confirm DATABASE_URL targets the correct cache database.
- Treat Ok(None) as 'instrument not cached' and handle it separately from this error.
Example fix
// before
let instrument = DatabaseQueries::load_instrument(&pool, &instrument_id).await?;
// after
let instrument = match DatabaseQueries::load_instrument(&pool, &instrument_id).await? {
Some(instrument) => Some(instrument),
None => {
tracing::warn!("instrument {instrument_id} not in cache");
None
}
}; Defensive patterns
Strategy: try-catch
Validate before calling
let exists: bool = sqlx::query_scalar(
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'instrument')",
).fetch_one(pool).await?;
if !exists {
return Err(anyhow::anyhow!("'instrument' table missing — run migrations"));
} Try / catch
match DatabaseQueries::load_instrument(&pool, &instrument_id).await {
Ok(Some(instrument)) => Some(instrument),
Ok(None) => {
tracing::warn!("instrument {instrument_id} not in cache");
None
}
Err(e) => return Err(e),
} Prevention
- Run matching migrations before loading instruments from the cache.
- Handle Ok(None) as 'not cached' separately from execution/decode errors.
- Keep reader and writer application versions aligned to avoid decode failures from new enum/kind values.
- Log the instrument_id together with the inner sqlx error to pinpoint schema drift.
When it happens
Trigger: Calling `DatabaseQueries::load_instrument(pool, instrument_id)` when the connection fails, the `instrument` table doesn't exist, or the row fails to decode (e.g. a newer instrument kind or asset_class value the current decoder rejects, or a malformed numeric column).
Common situations: Loading instruments at strategy startup from a database written by a different Nautilus version; fresh DB without migrations; rows containing new enum variants; transient network failure during the lookup.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Failed to load general table: {e}
- Failed to load currencies: {e}
- Failed to load currency: {e}
- Failed to insert item {} into instrument table: {:?}
- Failed to load instrument closes: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3b5aabdab7eb6242.
Report an issue: GitHub.