nautechsystems/nautilus_trader · error · anyhow::Error

Query account request failure, account should exist

Error message

Query account request failure, account should exist

What it means

query_address queries the cosmos auth module for an account by address; the gRPC response's optional `account` field is None when the account does not exist on chain. The library treats this as fatal because it needs account_number/sequence to sign transactions.

Source

Thrown at crates/adapters/dydx/src/grpc/client.rs:295

    /// Query account information for a given address.
    ///
    /// Returns the account number and sequence number needed for transaction signing.
    ///
    /// # Errors
    ///
    /// Returns an error if the query fails or the account does not exist.
    pub async fn query_address(&mut self, address: &str) -> Result<(u64, u64), anyhow::Error> {
        let req = QueryAccountRequest {
            address: address.to_string(),
        };
        let resp = self
            .auth
            .account(req)
            .await?
            .into_inner()
            .account
            .ok_or_else(|| {
                anyhow::anyhow!("Query account request failure, account should exist")
            })?;

        let account = BaseAccount::decode(&*resp.value)?;
        Ok((account.account_number, account.sequence))
    }

    /// Query for [an account](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth#account-1)
    /// by its address.
    ///
    /// # Errors
    ///
    /// Returns an error if the query fails or the account does not exist.
    pub async fn get_account(&mut self, address: &str) -> Result<BaseAccount, anyhow::Error> {
        let req = QueryAccountRequest {
            address: address.to_string(),
        };
        let resp = self
            .auth

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fund the account or send any transaction to it so the BaseAccount is created on chain.
  2. Verify the address is valid for the connected network (correct bech32 prefix dydx...).
  3. Point the gRPC client at the correct network endpoint for the account.
  4. Handle the empty case in caller code by treating it as account-not-found rather than retrying.

Example fix

// before
let (number, seq) = client.query_address(addr).await?;
// after: ensure account exists on chain first
match client.query_address(addr).await {
    Ok(res) => res,
    Err(e) if e.to_string().contains("account should exist") => {
        anyhow::bail!("Account {addr} has no on-chain state; fund it or use a different address")
    }
    Err(e) => Err(e),
}
Defensive patterns

Strategy: validation

Validate before calling

let info = key_info.address();
anyhow::ensure!(info.starts_with("dydx"), "address {info} has wrong bech32 prefix");

Try / catch

match client.query_address(addr).await {
    Ok(res) => res,
    Err(e) if e.to_string().contains("account should exist") => anyhow::bail!("account {addr} not initialized on chain; fund it first"),
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling query_address for an address that has never been funded or has not sent/received any transaction on the dydx chain.

Common situations: Using a freshly generated wallet key with no on-chain activity; wrong network (testnet address queried on mainnet RPC); typo'd or malformed bech32 address prefix.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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