nautechsystems/nautilus_trader · error · anyhow::Error

Steam pool event transform error: {e}

Error message

Steam pool event transform error: {e}

What it means

This error is produced inside the row-streaming closure when `transform_row_to_dex_pool_data` fails to convert a database row into a DEX pool event. The library maps per-row transform errors into anyhow errors so the stream yields a Result per item; a row that does not match the expected schema shape causes this.

Source

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

                .bind(pool_identifier.to_string())
                .bind(pos.number as i64)
                .bind(pos.transaction_index as i32)
                .bind(pos.log_index as i32)
                .bind(to_block.map(|block| block as i64))
                .fetch(&self.pool)
        } else {
            sqlx::query(QUERY_ALL)
                .bind(chain.chain_id as i32)
                .bind(pool_identifier.to_string())
                .bind(to_block.map(|block| block as i64))
                .fetch(&self.pool)
        };

        // Transform rows to events
        let stream = query.map(move |row_result| match row_result {
            Ok(row) => {
                transform_row_to_dex_pool_data(&row, chain.clone(), dex.clone(), instrument_id)
                    .map_err(|e| anyhow::anyhow!("Steam pool event transform error: {e}"))
            }
            Err(e) => Err(anyhow::anyhow!("Stream pool events database error: {e}")),
        });

        Box::pin(stream)
    }

    /// Persists an execution transaction record to the `execution_transaction` table.
    ///
    /// Records are written before broadcast so a signed transaction is never forgotten;
    /// the unique `(chain_id, transaction_hash)` constraint makes an exact re-insertion
    /// idempotent. Signer nonce ownership and order IDs are unique before broadcast. Order
    /// submission records carry the client order ID; operator transactions (wrap, approve)
    /// store `NULL`.
    ///
    /// # Errors
    ///
    /// Returns an error if the database operation fails.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the failing row's contents and inner transform error to find the offending column
  2. Check that the table schema matches the version transform_row_to_dex_pool_data expects
  3. Re-run or repair rows with NULLs or malformed values
  4. Ensure both writer and reader use the same schema version/migrations

Example fix

// before
.map_err(|e| anyhow::anyhow!("Steam pool event transform error: {e}"))
// after
.map_err(|e| {
    tracing::warn!(error = %e, "skipping malformed pool row");
    anyhow::anyhow!("Steam pool event transform error: {e}")
})
Defensive patterns

Strategy: validation

Validate before calling

// validate expected columns on a sample row before streaming
let required = ["tick_value", "liquidity_gross", "pool_address"];
// after fetching first row, check each column with row.try_get::<_, ...>

Try / catch

match transform_row_to_dex_pool_data(&row, ...) {
    Ok(ev) => emit(ev),
    Err(e) => { tracing::warn!(error = %e, "row skipped"); skip(); }
}

Prevention

When it happens

Trigger: Streaming pool events where a row is missing an expected column, has a value of the wrong type (e.g. malformed numeric/text for parsing), or the transformer's internal parsing (addresses, decimals, instrument ID construction) fails for that row.

Common situations: Schema drift between writer and reader versions; rows written by a different chain/dex exporter with unexpected nulls or formats; corrupted or manually edited rows.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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