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 = $4View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the wrapped `{e}`: 'relation does not exist' → run migrations; 'connection refused' → fix DATABASE_URL/network
- Verify migrations have been applied to the target database (check the migrations table) before querying
- Validate chain_id fits in i32 and from_block fits in i64 before binding
- 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
- Apply migrations as part of deployment/startup
- Point DATABASE_URL at the correct database and verify with a startup smoke query
- Add bounded retry with backoff for transient connection errors
- Validate numeric ranges before binding to i32/i64 parameters
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
- Failed to number verified action evidence: {e}
- Failed to load active execution intent: {e}
- Failed to seed chain table: {e}
- Failed to call create_block_partition for chain {}: {e}
- Failed to call create_token_partition for chain {}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/eb43c98526c67832.
Report an issue: GitHub.