nautechsystems/nautilus_trader · error · anyhow::Error

Failed to insert into pool_liquidity table: {e}

Error message

Failed to insert into pool_liquidity table: {e}

What it means

Wraps a failed sqlx INSERT into the `pool_liquidity` table for mint/burn liquidity position events. Any Postgres-level failure (constraint, type, connection) is converted into this anyhow error. The originating database error text is always included after the colon.

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:1289

        .bind(chain_id as i32)
        .bind(liquidity_update.dex.name.to_string())
        .bind(liquidity_update.pool_identifier.as_str())
        .bind(liquidity_update.block as i64)
        .bind(liquidity_update.transaction_hash.as_str())
        .bind(liquidity_update.transaction_index as i32)
        .bind(liquidity_update.log_index as i32)
        .bind(liquidity_update.kind.to_string())
        .bind(liquidity_update.sender.map(|sender| sender.to_string()))
        .bind(liquidity_update.owner.to_string())
        .bind(U128Pg(liquidity_update.position_liquidity))
        .bind(U256Pg(liquidity_update.amount0))
        .bind(U256Pg(liquidity_update.amount1))
        .bind(liquidity_update.tick_lower)
        .bind(liquidity_update.tick_upper)
        .execute(&self.pool)
        .await
        .map(|_| ())
        .map_err(|e| anyhow::anyhow!("Failed to insert into pool_liquidity table: {e}"))
    }

    /// Retrieves all valid token records for the given chain and converts them into `Token` domain objects.
    ///
    /// Only returns tokens that do not contain error information, filtering out invalid tokens
    /// that were previously recorded with error details.
    ///
    /// # Errors
    ///
    /// Returns an error if the database query fails.
    pub async fn load_tokens(&self, chain: SharedChain) -> anyhow::Result<Vec<Token>> {
        sqlx::query_as::<_, TokenRow>("SELECT * FROM token WHERE chain_id = $1 AND error IS NULL")
            .bind(chain.chain_id as i32)
            .fetch_all(&self.pool)
            .await
            .map(|rows| {
                rows.into_iter()
                    .map(|token_row| {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the embedded SQLSTATE/constraint name; for FK violations persist the pool before its liquidity events.
  2. Verify U256 amounts are converted to a column-compatible representation (numeric/bytea) without overflow.
  3. Run pending migrations so `pool_liquidity` matches the query's columns.
  4. If replaying historical ranges, chunk the work and retry on transient connection errors.

Example fix

// before: insert liquidity events for any pool
self.insert_pool_liquidity(&liquidity_update).await?;
// after: skip pools absent from the cache
if self.load_pool(chain, dex_id, &liquidity_update.pool_identifier).await?.is_some() {
    self.insert_pool_liquidity(&liquidity_update).await?;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check liquidity values fit the column types before writing
let liquidity_fits = amount0 <= U256::from(u128::MAX) && amount1 <= U256::from(u128::MAX);
if !liquidity_fits { return Err(anyhow!("liquidity amount exceeds storage column")); }

Try / catch

if let Err(e) = self.insert_pool_liquidity(&update).await {
    if e.to_string().contains("foreign key") {
        log::warn!("liquidity event for unpersisted pool skipped");
    } else {
        return Err(e);
    }
}

Prevention

When it happens

Trigger: Calling the liquidity-event insert (database.rs, insert into `pool_liquidity`) when a bind fails or the statement errors: FK violation for a missing pool row, NOT NULL on amount0/amount1/tick fields, or U256 liquidity amounts that cannot be stored in the target column type.

Common situations: Processing mint/burn events for pools that were filtered out or not yet synced; schema drift between adapter expectations and the deployed migration state; oversized liquidity values from high-volume pools; connection loss during bulk event replay.

Related errors


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