nautechsystems/nautilus_trader · error
Failed to load position ids: {e}
Error message
Failed to load position ids: {e} What it means
load_positions first queries the distinct position_ids from the position events table; if that SELECT fails the sqlx error is wrapped in this message. No positions are returned because the id enumeration itself failed.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:991
/// # Errors
///
/// Returns an error if loading position IDs or replaying any position fails.
pub async fn load_positions(pool: &PgPool) -> anyhow::Result<Vec<Position>> {
let position_ids: Vec<PositionId> = sqlx::query(
r#"
SELECT DISTINCT position_id
FROM "position_event"
ORDER BY position_id ASC
"#,
)
.fetch_all(pool)
.await
.map(|rows| {
rows.into_iter()
.map(|row| PositionId::from(row.get::<&str, _>(0)))
.collect()
})
.map_err(|e| anyhow::anyhow!("Failed to load position ids: {e}"))?;
let mut positions = Vec::new();
for id in position_ids {
match Self::load_position(pool, &id).await {
Ok(Some(position)) => positions.push(position),
Ok(None) => log::error!("Position not found: {id}"),
Err(e) => log::error!("Failed to load position {id}: {e}"),
}
}
Ok(positions)
}
async fn insert_position_event(
transaction: &mut Transaction<'_, Postgres>,
event: &OrderFilled,
) -> anyhow::Result<()> {View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the wrapped sqlx error for the root cause.
- Run the nautilus SQL migrations so the position tables exist.
- Confirm the venue/instance filters match data actually written to this database.
- Verify connectivity and privileges, then retry if the failure was transient.
Defensive patterns
Strategy: retry
Validate before calling
sqlx::query("SELECT 1 FROM position_event LIMIT 1").fetch_optional(&pool).await?; Try / catch
match load_positions(&pool, &venue).await {
Err(e) if is_transient_db_error(&e) => retry_with_backoff(3),
other => other,
} Prevention
- Run migrations before first use of the SQL cache.
- Confirm venue/instance filters match the data in this database.
- Grant the DB user the required SELECT privileges.
When it happens
Trigger: Calling DatabaseQuery::load_positions(pool, venue) and the id query errors: missing table, connection failure, or SQL error wrapped via anyhow.
Common situations: Database not migrated; wrong venue filter against an empty/uninitialized schema; connectivity loss at query time; insufficient SELECT privileges.
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 from execution_transaction table: {e}
- Failed to load instruments: {e}
- Failed to insert instrument close: {e}
- Failed to load instrument closes: {e}
- Failed to insert into trader table: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/553c65375eb8aa3c.
Report an issue: GitHub.