nautechsystems/nautilus_trader · error · anyhow::Error

Subaccount query response does not contain subaccount

Error message

Subaccount query response does not contain subaccount

What it means

get_subaccount queries the dYdX subaccounts module; `subaccount` is optional and None when no subaccount exists for the given owner/number pair. The library raises instead of returning an empty subaccount.

Source

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

    ///
    /// Returns an error if the query fails.
    pub async fn get_subaccount(
        &mut self,
        address: &str,
        number: u32,
    ) -> Result<SubaccountInfo, anyhow::Error> {
        let req = QueryGetSubaccountRequest {
            owner: address.to_string(),
            number,
        };
        let subaccount = self
            .subaccounts
            .subaccount(req)
            .await?
            .into_inner()
            .subaccount
            .ok_or_else(|| {
                anyhow::anyhow!("Subaccount query response does not contain subaccount")
            })?;
        Ok(subaccount)
    }

    /// Simulate a transaction to estimate gas usage.
    ///
    /// # Errors
    ///
    /// Returns an error if simulation fails.
    pub async fn simulate_tx(&mut self, tx_bytes: Vec<u8>) -> Result<u64, anyhow::Error> {
        let req = SimulateRequest {
            tx_bytes,
            ..Default::default()
        };
        let gas_used = self
            .tx
            .simulate(req)
            .await?

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Deposit funds or perform any subaccount action first to create it on chain.
  2. Confirm the owner address and subaccount number (usually 0) are correct.
  3. Ensure the gRPC endpoint targets the network where the subaccount exists (mainnet vs testnet).
  4. Handle the not-found case explicitly in caller logic instead of treating it as a transient failure.

Example fix

// before
let sub = client.get_subaccount(owner, 0).await?;
// after: validate existence expectations
let sub = client.get_subaccount(owner, subaccount_id.number).await
    .map_err(|e| anyhow::anyhow!("Subaccount {owner}/{n} not found — has it been funded? ({e})"))
    .map_err(...); // or create/init subaccount before querying
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(subaccount_number >= 0, "subaccount number must be non-negative");
// optionally pre-check existence at startup:
// client.get_subaccount(owner, 0).await.expect("subaccount must exist");

Try / catch

let sub = client.get_subaccount(owner, number).await
    .map_err(|e| if e.to_string().contains("does not contain subaccount") {
        anyhow::anyhow!("subaccount {owner}/{number} not initialized; deposit first")
    } else { e })?;

Prevention

When it happens

Trigger: Calling get_subaccount with (address, subaccount_number) that has never been created on chain — e.g. subaccount 0 for an address that never opened a position or deposit.

Common situations: Configuring a bot with an owner address whose subaccounts were never initialized; querying a different network than where the subaccount was created; using a subaccount number other than the default 0 that doesn't exist.

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/71236dace257242a. Report an issue: GitHub.