nautechsystems/nautilus_trader · error
Failed to persist execution client {client_id}: {e}
Error message
Failed to persist execution client {client_id}: {e} What it means
Within index_order_clients, the INSERT INTO "client" (id) ... ON CONFLICT DO NOTHING for the execution client failed; sqlx error wrapped in anyhow. This step upserts the client row before linking order events, so failure means the `client` table is missing/mismatched or the transaction connection broke. The transaction is aborted as a result.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:1480
if let Some(conflicting_client_id) = conflicting_client_id {
anyhow::bail!(
"Order {client_order_id} is already claimed by execution client \
{conflicting_client_id} and cannot be claimed by {client_id}"
);
}
sqlx::query(
r#"
INSERT INTO "client" (id)
VALUES ($1)
ON CONFLICT (id) DO NOTHING
"#,
)
.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}");
}View on GitHub (pinned to 18893faf8b)
Solutions
- Read the chained sqlx error to identify missing table vs connection failure.
- Run the full cache schema initialization so the `client` table exists.
- Check DB connectivity and re-run index_order_clients; the transaction rolls back so it is safe to retry.
- Verify the `client.id` column type/size fits your client_id strings.
Example fix
// before
queries::postgres::index_order_clients(&mut tx, &client_order_id, &client_id).await?;
// after
sqlx::query(r#"CREATE TABLE IF NOT EXISTS "client" (id VARCHAR PRIMARY KEY)"#)
.execute(&mut *tx).await?;
queries::postgres::index_order_clients(&mut tx, &client_order_id, &client_id).await?; Defensive patterns
Strategy: validation
Validate before calling
let client_table = sqlx::query(r#"SELECT 1 FROM \"client\" LIMIT 1"#).fetch_optional(pool).await.is_ok(); anyhow::ensure!(client_table, "client table missing; run cache schema init first");
Try / catch
match queries::postgres::index_order_clients(&mut tx, &client_order_id, &client_id).await {
Err(e) if e.to_string().contains("Failed to persist execution client") => {
anyhow::bail!("cache schema incomplete: {e:#}");
}
other => other?,
} Prevention
- Run the complete schema init (client, order_event, indexes) before indexing
- Verify client.id column type fits your client_id strings
- Check connectivity before long rebuilds
- Retry safely — the transaction rolls back atomically
When it happens
Trigger: Calling index_order_clients when the `client` table does not exist or its `id` column type cannot accept the client_id string, or the DB connection fails during the INSERT.
Common situations: Partially initialized cache DB (order_event exists but client table missing); schema created by an older nautilus version; connection dropped mid-transaction.
Related errors
- Failed to insert into bar table: {e}
- Failed to insert into order_position_index table: {e}
- Failed to insert instrument close: {e}
- Failed to load bars: {e}
- Failed to validate order client origin: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5ca8d9fe3e05e1e5.
Report an issue: GitHub.