nautechsystems/nautilus_trader · error · anyhow::Error

Failed to load block timestamps: {e}

Error message

Failed to load block timestamps: {e}

What it means

The query that loads block timestamps for a chain within a block range (`WHERE chain_id = $1 AND number >= $2 ...`) failed; the sqlx error is wrapped with this message. This is a read-path error surfaced while the indexer needs timestamps for historical pool events.

Source

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

                number,
                timestamp
            FROM (
                SELECT number, timestamp, 0 AS source_order
                FROM block
                WHERE chain_id = $1 AND number >= $2 AND timestamp IS NOT NULL
                UNION ALL
                SELECT number, timestamp, 1 AS source_order
                FROM pool_event_block
                WHERE chain_id = $1 AND number >= $2 AND timestamp IS NOT NULL
            ) AS block_timestamps
            ORDER BY number ASC, source_order ASC
            ",
        )
        .bind(chain.chain_id as i32)
        .bind(from_block as i64)
        .fetch_all(&self.pool)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to load block timestamps: {e}"))
    }

    /// Adds or updates a DEX (Decentralized Exchange) record in the database.
    ///
    /// # Errors
    ///
    /// Returns an error if the database operation fails.
    pub async fn add_dex(&self, dex: SharedDex) -> anyhow::Result<()> {
        sqlx::query(
            "
            INSERT INTO dex (
                chain_id, name, factory_address, creation_block
            ) VALUES ($1, $2, $3, $4)
            ON CONFLICT (chain_id, name)
            DO UPDATE
            SET
                factory_address = $3,
                creation_block = $4

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped `{e}`: 'relation does not exist' → run migrations; 'connection refused' → fix DATABASE_URL/network
  2. Verify migrations have been applied to the target database (check the migrations table) before querying
  3. Validate chain_id fits in i32 and from_block fits in i64 before binding
  4. Retry transient connection errors with backoff; increase the pool's acquire timeout if under load

Example fix

// before
let rows = loader.load_timestamps(chain, from_block).await?;
// after: guard and retry transient failures
if chain.chain_id > i32::MAX as u64 { return Err(anyhow::anyhow!("chain_id exceeds i32")); }
let rows = retry_backoff(|| loader.load_timestamps(chain, from_block)).await?;
Defensive patterns

Strategy: retry

Validate before calling

anyhow::ensure!(chain.chain_id <= i32::MAX as u64, "chain_id exceeds i32");
anyhow::ensure!(from_block >= 0 && from_block <= i64::MAX, "from_block out of i64 range");
// migrations applied?
let v: Option<i32> = sqlx::query_scalar("SELECT 1 FROM information_schema.tables WHERE table_name = 'block'").fetch_optional(&pool).await?;
anyhow::ensure!(v.is_some(), "block table missing; run migrations");

Type guard

fn query_args_valid(chain_id: u64, from_block: i64) -> bool {
    chain_id <= i32::MAX as u64 && (0..=i64::MAX).contains(&from_block)
}

Try / catch

let rows = match loader.load_block_timestamps(&chain, from_block).await {
    Ok(r) => r,
    Err(e) if is_transient(&e) => backoff_retry(|| loader.load_block_timestamps(&chain, from_block)).await?,
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling the block-timestamp loader with a chain_id/from_block that exposes a cast problem (chain_id exceeding i32), the `block` or `pool_event_block` table missing, connection failure/timeout during `.fetch_all`, or a type mismatch between the query's expected columns and the actual schema.

Common situations: Pointing the service at a fresh/empty database where migrations never ran; wrong DATABASE_URL pointing to another service's schema; Postgres restart mid-query; chain_id values beyond i32 range on exotic chains.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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