nautechsystems/nautilus_trader · error

Failed to index order client origin: {e}

Error message

Failed to index order client origin: {e}

What it means

index_order_clients wraps the failure of the final UPDATE "order_event" SET client_id = $2 WHERE client_order_id = $1 as 'Failed to index order client origin'. This is the core write of the client-id mapping; any sqlx error here (missing column, connection loss, lock timeout) aborts the transaction. Distinct from the rows_affected==0 bail which is the 'No persisted order events' error.

Source

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

            )
            .bind(client_id.to_string())
            .execute(&mut *transaction)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to persist execution client {client_id}: {e}"))?;

            let result = sqlx::query(
                r#"
                UPDATE "order_event"
                SET client_id = $2
                WHERE client_order_id = $1
                  AND (client_id IS NULL OR client_id = $2)
            "#,
            )
            .bind(client_order_id.to_string())
            .bind(client_id.to_string())
            .execute(&mut *transaction)
            .await
            .map_err(|e| anyhow::anyhow!("Failed to index order client origin: {e}"))?;

            if result.rows_affected() == 0 {
                anyhow::bail!("No persisted order events found for {client_order_id}");
            }
        }

        transaction
            .commit()
            .await
            .map_err(|e| anyhow::anyhow!("Failed to commit order client origins: {e}"))
    }

    /// Inserts or updates an order ID to position ID index entry via the provided `pool`.
    ///
    /// # Errors
    ///
    /// Returns an error if the SQL INSERT or UPDATE operation fails.
    pub async fn index_order_position(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the chained sqlx error for the exact DB complaint.
  2. Re-run schema initialization/migrations so `order_event` has client_order_id and client_id columns as expected.
  3. Retry the operation after transient errors — the transaction rollback leaves state consistent.
  4. Avoid concurrent writers on the same order rows or use appropriate isolation.

Example fix

// before
queries::postgres::index_order_clients(&mut tx, &client_order_id, &client_id).await?;
// after
let result = queries::postgres::index_order_clients(&mut tx, &client_order_id, &client_id).await;
if let Err(e) = &result {
    tracing::error!(source = ?std::error::Error::source(e), "order client indexing failed");
}
result?;
Defensive patterns

Strategy: try-catch

Validate before calling

let cols = sqlx::query(r#"SELECT column_name FROM information_schema.columns WHERE table_name = 'order_event'"#)
    .fetch_all(pool).await?;
let names: Vec<_> = cols.into_iter().map(|r| r.get::<String, _>(0)).collect();
anyhow::ensure!(names.contains(&"client_id".to_string()), "order_event.client_id column missing");

Try / catch

match queries::postgres::index_order_clients(&mut tx, &client_order_id, &client_id).await {
    Ok(()) => (),
    Err(e) => {
        tracing::error!(source = ?std::error::Error::source(&e), "order client origin update failed");
        return Err(e); // tx rolled back; safe to retry later
    }
}

Prevention

When it happens

Trigger: Calling index_order_clients when the UPDATE fails: order_event table/columns mismatch current query, DB connection drops during execute, or the row is locked by another writer.

Common situations: Schema drift after upgrade (order_event columns renamed); long-running rebuild colliding with concurrent writers; DB restart mid-transaction.

Related errors


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