nautechsystems/nautilus_trader · error · anyhow::Error
Failed to insert into pool_swap table: {e}
Error message
Failed to insert into pool_swap table: {e} What it means
Wraps a failed sqlx INSERT into the `pool_swap` table, which persists pool swap transaction events. The real Postgres error is embedded in the message. It is raised whenever the swap-event insert query cannot complete (constraint, connection, or type error).
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:1248
.bind(swap.transaction_hash.as_str())
.bind(swap.transaction_index as i32)
.bind(swap.log_index as i32)
.bind(swap.sender.to_string())
.bind(swap.recipient.to_string())
.bind(swap.sqrt_price_x96.to_string())
.bind(swap.liquidity.to_string())
.bind(swap.tick)
.bind(swap.amount0.to_string())
.bind(swap.amount1.to_string())
.bind(order_side)
.bind(base_quantity)
.bind(quote_quantity)
.bind(spot_price)
.bind(execution_price)
.execute(&self.pool)
.await
.map(|_| ())
.map_err(|e| anyhow::anyhow!("Failed to insert into pool_swap table: {e}"))
}
/// Persists a liquidity position change (mint/burn) event to the `pool_liquidity` table.
///
/// # Errors
///
/// Returns an error if the database operation fails.
pub async fn add_pool_liquidity_update(
&self,
chain_id: u32,
liquidity_update: &PoolLiquidityUpdate,
) -> anyhow::Result<()> {
sqlx::query(
"
INSERT INTO pool_liquidity_event (
chain_id, dex_name, pool_identifier, block, transaction_hash, transaction_index, log_index,
event_type, sender, owner, position_liquidity, amount0, amount1, tick_lower, tick_upper
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the embedded Postgres error for the failing constraint (e.g. pool_id FK) and insert the parent pool row first.
- If it is a FK/ordering problem, ensure pool records are persisted before their swaps, or add the pool with ON CONFLICT DO NOTHING.
- Check bound numeric types (spot_price, execution_price, quantities) match column precision/scale.
- Validate pool connectivity and that the `pool_swap` table exists via current migrations.
Example fix
// before: insert swaps unconditionally
.map_err(|e| anyhow::anyhow!("Failed to insert into pool_swap table: {e}"))
// after: guard that the pool exists before persisting its swap
if self.load_pool(chain, dex_id, pool_identifier).await?.is_some() {
self.insert_pool_swap(/* ... */).await?;
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the referenced pool exists before writing its swap
let pool_exists: Option<(i64,)> = sqlx::query_as(
"SELECT 1 FROM pool WHERE chain_id = $1 AND pool_address = $2",
)
.bind(chain_id).bind(pool_address)
.fetch_optional(&pool).await?;
if pool_exists.is_none() { return Err(anyhow!("pool {pool_address} not persisted yet")); } Try / catch
match self.insert_pool_swap(/* ... */).await {
Ok(()) => {}
Err(e) if e.to_string().contains("foreign key") => log::warn!("swap for unknown pool dropped: {e}"),
Err(e) => return Err(e),
} Prevention
- Persist pool metadata before swap events for that pool.
- Keep numeric precision within the column's numeric(precision, scale).
- Ping the database before long event-replay batches.
- Align deployed schema version with adapter expectations.
When it happens
Trigger: Calling the swap-persistence method (database.rs, insert into `pool_swap`) with values that violate the table schema: e.g. a foreign-key violation because the pool row does not exist yet, a NOT NULL column receiving a missing quantity/price, or oversized U256/decimal values that overflow the column type.
Common situations: Storing swaps before the corresponding pool was inserted (FK violation); a token with wrong decimals causing quantity parsing errors; DB connection idle-timed out mid-sync; column length/type mismatch after a schema change.
Related errors
- Failed to insert into pool_liquidity table: {e}
- Failed to persist pre-sign verification: {e}
- Failed to seed chain table: {e}
- Failed to call create_block_partition for chain {}: {e}
- Failed to call create_token_partition for chain {}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e370cfd51818b93e.
Report an issue: GitHub.