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 = $4View on GitHub (pinned to 18893faf8b)
Solutions
- Run database migrations to ensure the DEX sync checkpoint table exists
- Verify the app writes to the primary, not a read-only replica
- Check the underlying sqlx error message for constraint/connection details
- 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
- Run migrations at deployment start
- Write checkpoints to the primary database, never a replica
- Retry transient errors after long sync runs
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
- Failed to update pool last synced block: {e}
- Failed to get dex last synced block: {e}
- Failed to get pool last synced block: {e}
- Failed to update {event_family} pool event-family checkpoint
- Failed to finalize pool event sync progress: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2242088b61594acd.
Report an issue: GitHub.