nautechsystems/nautilus_trader · error · anyhow::Error

Failed to load invalid token addresses: {e}

Error message

Failed to load invalid token addresses: {e}

What it means

Wraps failures while loading invalid token addresses for a chain: either the SELECT of addresses fails, or any returned address string fails `validate_address`. Both paths are funneled into this single anyhow error.

Source

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

    /// Retrieves all invalid token addresses for a given chain.
    ///
    /// # Errors
    ///
    /// Returns an error if the database query fails or address validation fails.
    pub async fn load_invalid_token_addresses(
        &self,
        chain_id: u32,
    ) -> anyhow::Result<Vec<Address>> {
        sqlx::query_as::<_, (String,)>(
            "SELECT address FROM token WHERE chain_id = $1 AND error IS NOT NULL",
        )
        .bind(chain_id as i32)
        .fetch_all(&self.pool)
        .await?
        .into_iter()
        .map(|(address,)| validate_address(&address))
        .collect::<Result<Vec<_>, _>>()
        .map_err(|e| anyhow::anyhow!("Failed to load invalid token addresses: {e}"))
    }

    /// Loads pool data from the database for the specified chain and DEX.
    ///
    /// # Errors
    ///
    /// Returns an error if the database query fails, the connection to the database is lost, or the query parameters are invalid.
    pub async fn load_pools(
        &self,
        chain: SharedChain,
        dex_id: &str,
    ) -> anyhow::Result<Vec<PoolRow>> {
        sqlx::query_as::<_, PoolRow>(AssertSqlSafe(format!(
            "SELECT {POOL_ROW_COLUMNS} FROM pool WHERE chain_id = $1 AND dex_name = $2 ORDER BY creation_block ASC"
        )))
        .bind(chain.chain_id as i32)
        .bind(dex_id)
        .fetch_all(&self.pool)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Identify the failing address from the error and delete or correct the invalid row.
  2. Re-validate stored addresses against checksum format before relying on the invalid-token set.
  3. Check that the underlying table exists and migrations are current.
  4. Retry if the embedded error indicates a transient connection failure.

Example fix

// before
.map_err(|e| anyhow::anyhow!("Failed to load invalid token addresses: {e}"))
// after: purge rows that cannot validate
// DELETE FROM invalid_token WHERE address !~ '^0x[0-9a-fA-F]{40}$';
Defensive patterns

Strategy: validation

Validate before calling

// pre-filter addresses that cannot pass validation
let valid_hex = |a: &str| a.len() == 42 && a.starts_with("0x") && a[2..].chars().all(|c| c.is_ascii_hexdigit());

Try / catch

let invalid = self.load_invalid_addresses(chain).await.unwrap_or_else(|e| {
    log::warn!("invalid-token set unavailable, treating as empty: {e}");
    HashSet::new()
});

Prevention

When it happens

Trigger: Calling the invalid-address loading method (database.rs) when the SELECT errors (connection loss, missing table) or when a stored address fails `validate_address`, e.g. a row containing an empty string, wrong-length hex, or non-hex characters.

Common situations: Legacy rows written by an older adapter version that stored addresses without checksum/validation; manual data edits in the DB; database connectivity problems during startup cache warm-up.

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/523690437d807d35. Report an issue: GitHub.