nautechsystems/nautilus_trader · error

Client {client_id} not found

Error message

Client {client_id} not found

What it means

generate_mass_status resolves the execution client adapter by client_id via get_client_adapter_mut; if no adapter with that ID is registered in the engine, it bails with this error instead of returning a status.

Source

Thrown at crates/execution/src/engine/mod.rs:435

        client_id: &ClientId,
    ) -> Option<&mut ExecutionClientAdapter> {
        self.clients.get_mut(client_id)
    }

    /// Generates mass status for the given client.
    ///
    /// # Errors
    ///
    /// Returns an error if the client is not found or mass status generation fails.
    pub async fn generate_mass_status(
        &mut self,
        client_id: &ClientId,
        lookback_mins: Option<u64>,
    ) -> anyhow::Result<Option<ExecutionMassStatus>> {
        if let Some(client) = self.get_client_adapter_mut(client_id) {
            client.generate_mass_status(lookback_mins).await
        } else {
            anyhow::bail!("Client {client_id} not found")
        }
    }

    /// Registers an external order with the execution client for tracking.
    ///
    /// This is called after reconciliation creates an external order, allowing the
    /// execution client to track it for subsequent events (e.g., cancellations).
    pub fn register_external_order(
        &self,
        client_order_id: ClientOrderId,
        venue_order_id: VenueOrderId,
        instrument_id: InstrumentId,
        strategy_id: StrategyId,
        ts_init: UnixNanos,
    ) {
        let venue = instrument_id.venue;
        // Prefer the cached origin over venue routing so tracking lands on the
        // client whose stream materialized the order.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the client is registered (register_client succeeded) before requesting mass status.
  2. Use the exact client_id the adapter was registered with; log/enumerate registered clients to confirm.
  3. Re-register the client if it was deregistered, then retry generate_mass_status.
  4. Handle the error path in reconciliation so a missing client is skipped/logged rather than aborting the whole reconciliation.

Example fix

// before
let status = engine.generate_mass_status(&client_id, None).await?; // bails if unknown
// after
if engine.get_client_adapter(&client_id).is_some() {
    let status = engine.generate_mass_status(&client_id, None).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

if engine.get_client_adapter(client_id).is_some() {
    let status = engine.generate_mass_status(client_id, lookback_mins).await?;
}

Try / catch

match engine.generate_mass_status(client_id, lookback).await {
    Err(e) if e.to_string().contains("not found") => log::warn!("client {client_id} unavailable for mass status, skipping"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling ExecutionEngine::generate_mass_status(client_id, lookback_mins) with a client_id that has no registered adapter — never registered, deregistered, or a typo/mismatched ID.

Common situations: Requesting a mass status report during reconciliation for a client that failed to register at startup; using an ID from config that differs from the registered adapter's client_id; calling after deregister_client removed the client.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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