nautechsystems/nautilus_trader · error

Failed to load position events: {e}

Error message

Failed to load position events: {e}

What it means

load_position_events runs a SELECT returning the fill events (JSON) for a position_id; when the query fails the sqlx error is wrapped in this message. The caller cannot replay the position because its events could not be read.

Source

Thrown at crates/infrastructure/src/sql/queries.rs:925

    ///
    /// Returns an error if the SQL SELECT or deserialization fails.
    pub async fn load_position_events(
        pool: &PgPool,
        position_id: &PositionId,
    ) -> anyhow::Result<Vec<OrderFilled>> {
        sqlx::query_as::<_, OrderFilledRow>(
            r#"
            SELECT *
            FROM "position_event"
            WHERE position_id = $1
            ORDER BY event_sequence ASC
        "#,
        )
        .bind(position_id.to_string())
        .fetch_all(pool)
        .await
        .map(|rows| rows.into_iter().map(|row| row.0).collect())
        .map_err(|e| anyhow::anyhow!("Failed to load position events: {e}"))
    }

    /// Loads and replays a complete `Position` for a `position_id` via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if loading events, loading instruments, or replaying fills fails.
    pub async fn load_position(
        pool: &PgPool,
        position_id: &PositionId,
    ) -> anyhow::Result<Option<Position>> {
        if let Some(snapshot) = Self::load_position_snapshot(pool, position_id).await?
            && let Some(replay_state) = snapshot.replay_state
        {
            return serde_json::from_value(replay_state)
                .map(Some)
                .map_err(|e| anyhow::anyhow!("Failed to decode position replay state: {e}"));
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped sqlx error for the exact cause (relation missing, decode error, connection).
  2. Apply the nautilus SQL migrations to create the position_event table.
  3. Verify the database connection settings point at the intended schema/database.
  4. If a row fails to decode as JSON, inspect and repair or remove the offending position_event row.
Defensive patterns

Strategy: retry

Validate before calling

sqlx::query("SELECT 1 FROM position_event LIMIT 1").fetch_optional(&pool).await?;

Try / catch

match load_position_events(&pool, &pid).await {
    Err(e) if is_transient_db_error(&e) => retry_with_backoff(3),
    other => other,
}

Prevention

When it happens

Trigger: Calling load_position_events(pool, position_id) where the fetch_all on the position events query errors: table missing, connection failure, or JSON column type mismatch.

Common situations: Schema not migrated; database unreachable; corrupted JSONB values causing decode errors during row fetch; wrong database pointed to by configuration.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4cc403ecaae64e56. Report an issue: GitHub.