{"record":{"id":"e370cfd51818b93e","repo":"nautechsystems/nautilus_trader","slug":"failed-to-insert-into-pool-swap-table-e","errorCode":null,"errorMessage":"Failed to insert into pool_swap table: {e}","messagePattern":"Failed to insert into pool_swap table: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/cache/database.rs","lineNumber":1248,"sourceCode":"        .bind(swap.transaction_hash.as_str())\n        .bind(swap.transaction_index as i32)\n        .bind(swap.log_index as i32)\n        .bind(swap.sender.to_string())\n        .bind(swap.recipient.to_string())\n        .bind(swap.sqrt_price_x96.to_string())\n        .bind(swap.liquidity.to_string())\n        .bind(swap.tick)\n        .bind(swap.amount0.to_string())\n        .bind(swap.amount1.to_string())\n        .bind(order_side)\n        .bind(base_quantity)\n        .bind(quote_quantity)\n        .bind(spot_price)\n        .bind(execution_price)\n        .execute(&self.pool)\n        .await\n        .map(|_| ())\n        .map_err(|e| anyhow::anyhow!(\"Failed to insert into pool_swap table: {e}\"))\n    }\n\n    /// Persists a liquidity position change (mint/burn) event to the `pool_liquidity` table.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the database operation fails.\n    pub async fn add_pool_liquidity_update(\n        &self,\n        chain_id: u32,\n        liquidity_update: &PoolLiquidityUpdate,\n    ) -> anyhow::Result<()> {\n        sqlx::query(\n            \"\n            INSERT INTO pool_liquidity_event (\n                chain_id, dex_name, pool_identifier, block, transaction_hash, transaction_index, log_index,\n                event_type, sender, owner, position_liquidity, amount0, amount1, tick_lower, tick_upper\n            ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)","sourceCodeStart":1230,"sourceCodeEnd":1266,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/cache/database.rs#L1230-L1266","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: insert swaps unconditionally\n.map_err(|e| anyhow::anyhow!(\"Failed to insert into pool_swap table: {e}\"))\n// after: guard that the pool exists before persisting its swap\nif self.load_pool(chain, dex_id, pool_identifier).await?.is_some() {\n    self.insert_pool_swap(/* ... */).await?;\n}","handlingStrategy":"try-catch","validationCode":"// ensure the referenced pool exists before writing its swap\nlet pool_exists: Option<(i64,)> = sqlx::query_as(\n    \"SELECT 1 FROM pool WHERE chain_id = $1 AND pool_address = $2\",\n)\n.bind(chain_id).bind(pool_address)\n.fetch_optional(&pool).await?;\nif pool_exists.is_none() { return Err(anyhow!(\"pool {pool_address} not persisted yet\")); }","typeGuard":null,"tryCatchPattern":"match self.insert_pool_swap(/* ... */).await {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"foreign key\") => log::warn!(\"swap for unknown pool dropped: {e}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["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."],"tags":["database","sqlx","postgres","insert-failed"],"backgroundTag":"database-write-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}