nautechsystems/nautilus_trader · error · anyhow::Error

Failed to get pool last synced block: {e}

Error message

Failed to get pool last synced block: {e}

What it means

Wraps a sqlx error from the SELECT reading the last synced block for a specific pool. It fires only on query failure; an absent row yields Ok(None) so callers can start from genesis or a configured start block.

Source

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

        dex: &DexType,
        pool_identifier: &PoolIdentifier,
    ) -> anyhow::Result<Option<u64>> {
        let result = sqlx::query_as::<_, (Option<i64>,)>(
            "
            SELECT
                last_full_sync_block_number
            FROM pool
            WHERE chain_id = $1
            AND dex_name = $2
            AND pool_identifier = $3
            ",
        )
        .bind(chain_id as i32)
        .bind(dex.to_string())
        .bind(pool_identifier.as_ref())
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to get pool last synced block: {e}"))?;

        Ok(result.and_then(|(block_number,)| block_number.map(|b| b as u64)))
    }

    pub(crate) async fn get_pool_event_sync_state(
        &self,
        chain_id: u32,
        dex: &DexType,
        pool_identifier: &PoolIdentifier,
    ) -> anyhow::Result<PoolEventSyncState> {
        let pool_state = sqlx::query_as::<_, (i32, Option<i64>)>(
            "
            SELECT event_sync_version, last_full_sync_block_number
            FROM pool
            WHERE chain_id = $1
            AND dex_name = $2
            AND pool_identifier = $3
            ",

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Apply pending migrations so the pool checkpoint table exists
  2. Check pool exhaustion (max_connections) if errors appear under concurrent load
  3. Retry the read; it is idempotent
  4. Inspect the wrapped sqlx error for the server-side cause
Defensive patterns

Strategy: fallback

Validate before calling

sqlx::query("SELECT 1 FROM pool_sync_checkpoints LIMIT 1").fetch_optional(&pool).await?;

Try / catch

let last_block = get_pool_last_synced_block(chain_id, dex, pool_id)
    .await
    .unwrap_or(None)
    .unwrap_or(start_block);

Prevention

When it happens

Trigger: Calling `get_pool_last_synced_block(chain_id, dex, pool_identifier)` when the connection fails, the checkpoint table is missing, or the query times out or errors on the server side.

Common situations: Missing migrations on fresh environments; DB failover mid-indexing; connection pool exhausted by concurrent sync tasks.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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