nautechsystems/nautilus_trader · error · anyhow::Error

Failed to update dex last synced block: {e}

Error message

Failed to update dex last synced block: {e}

What it means

Wraps a sqlx error from the UPDATE statement that persists the last synced block number for a DEX on a given chain. The library throws it whenever the upsert of the DEX sync checkpoint cannot complete. Until it succeeds, resume-from-checkpoint logic will fall back to an older block.

Source

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

        &self,
        chain_id: u32,
        dex: &DexType,
        block_number: u64,
    ) -> anyhow::Result<()> {
        sqlx::query(
            "
            UPDATE dex
            SET last_full_sync_pools_block_number = $3
            WHERE chain_id = $1 AND name = $2
            ",
        )
        .bind(chain_id as i32)
        .bind(dex.to_string())
        .bind(block_number as i64)
        .execute(&self.pool)
        .await
        .map(|_| ())
        .map_err(|e| anyhow::anyhow!("Failed to update dex last synced block: {e}"))
    }

    /// Updates the last synced block number for a pool.
    ///
    /// # Errors
    ///
    /// Returns an error if the database update fails.
    pub async fn update_pool_last_synced_block(
        &self,
        chain_id: u32,
        dex: &DexType,
        pool_identifier: &PoolIdentifier,
        block_number: u64,
    ) -> anyhow::Result<()> {
        sqlx::query(
            "
            UPDATE pool
            SET last_full_sync_block_number = $4

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Run database migrations to ensure the DEX sync checkpoint table exists
  2. Verify the app writes to the primary, not a read-only replica
  3. Check the underlying sqlx error message for constraint/connection details
  4. Retry the update; transient connection errors are common after long-running syncs

Example fix

// before
.map_err(|e| anyhow::anyhow!("Failed to update dex last synced block: {e}"))
// after
.map_err(|e| anyhow::anyhow!("Failed to update dex last synced block (chain={chain_id}, dex={dex}): {e}"))
Defensive patterns

Strategy: retry

Validate before calling

// Ensure checkpoint table exists before writing
sqlx::query("SELECT 1 FROM dex_sync_checkpoints LIMIT 1").fetch_optional(&pool).await?;

Try / catch

match update_dex_last_synced_block(chain_id, dex, block).await {
    Ok(_) => {}
    Err(e) if is_transient(&e) => retry_with_backoff(|| update_dex_last_synced_block(chain_id, dex, block)).await?,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `update_dex_last_synced_block(chain_id, dex, block_number)` when the pool connection fails, the target table is missing (migration not applied), a unique/foreign key constraint is violated, or the database is read-only.

Common situations: Fresh environment with unrun migrations; read-replica used for writes; database connection dropped after long sync runs; block_number exceeding i64 range (practically impossible for chains).

Related errors


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