nautechsystems/nautilus_trader · error
Failed to insert into client table: {e}
Error message
Failed to insert into client table: {e} What it means
Wraps failure of the INSERT into the client table performed by `add_order_event` when a `client_id` is supplied (a temporary step until client initialization is implemented). This runs inside the same transaction, so any failure rolls back the trader insert as well. Typically caused by constraint violations or connectivity issues on the client table.
Source
Thrown at crates/infrastructure/src/sql/queries.rs:653
.bind(order_event.trader_id().to_string())
.execute(&mut *transaction)
.await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into trader table: {e}"))?;
// Insert client if it does not exist
// TODO remove this when client initialization is implemented
if let Some(client_id) = 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(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into client table: {e}"))?;
}
let exec_algorithm_params = order_event
.exec_algorithm_params()
.map(serde_json::to_value)
.transpose()
.map_err(|e| anyhow::anyhow!("Failed to serialize exec algorithm params: {e}"))?;
let info = order_event
.info()
.map(serde_json::to_value)
.transpose()
.map_err(|e| anyhow::anyhow!("Failed to serialize order event info: {e}"))?;
sqlx::query(r#"
INSERT INTO "order_event" (
id, kind, client_order_id, order_type, order_side, trader_id, client_id, reason, strategy_id, instrument_id, trade_id, currency, quantity, time_in_force, liquidity_side,
post_only, reduce_only, quote_quantity, reconciliation, price, last_px, last_qty, trigger_price, trigger_type, limit_offset, trailing_offset,
trailing_offset_type, expire_time, display_qty, emulation_trigger, trigger_instrument_id, contingency_type,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect `{e}` for the exact sqlx cause (unique violation vs connection).
- Run migrations so the client table exists with the expected schema.
- Ensure the client_id string form matches what the schema expects.
- Retry `add_order_event` — the transaction rolls back cleanly on failure.
Example fix
// before
add_order_event(&mut tx, &event, Some(client_id.clone())).await?;
// after
add_order_event(&mut tx, &event, Some(client_id.clone())).await
.with_context(|| format!("persisting event for client {client_id}"))?; Defensive patterns
Strategy: try-catch
Validate before calling
sqlx::query(r#"SELECT EXISTS(SELECT 1 FROM "client" WHERE id = $1)"#)
.bind(client_id.to_string())
.fetch_one(pool).await
.map_err(|e| anyhow::anyhow!("client table unavailable: {e}"))?; Type guard
fn is_duplicate_client(e: &anyhow::Error) -> bool {
e.to_string().contains("duplicate key")
} Try / catch
match add_order_event(&mut tx, &event, Some(client_id.clone())).await {
Ok(()) => {}
Err(e) if is_duplicate_client(&e) => { /* client already registered — safe to continue */ }
Err(e) => return Err(e),
} Prevention
- Pre-register clients during initialization instead of relying on add_order_event.
- Verify the client table schema before deployments.
- Keep client_id formatting canonical (uppercase/lowercase consistently).
When it happens
Trigger: Calling `add_order_event` with `Some(client_id)` when the client table is missing, the client row violates a unique/constraint rule, or the connection fails mid-transaction.
Common situations: Schema not migrated; duplicate client_id with conflicting columns; database failover during write; client_id string format mismatched with the column type.
Related errors
- Failed to lock execution intent for nonce assignment: {e}
- Failed to persist pre-sign verification: {e}
- Failed to insert into trader table: {e}
- Failed to insert into order table: {e}
- Failed to insert into position table: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/05bc30e1796e96d0.
Report an issue: GitHub.