nautechsystems/nautilus_trader · error

Data client '{name}' is already registered

Error message

Data client '{name}' is already registered

What it means

Thrown by `add_data_client_with_routing` on the live node `NodeBuilder` when a data client factory is registered under a name that already exists in `data_client_factories`. Each data client must have a unique name so configs and routing tables stay unambiguous.

Source

Thrown at crates/live/src/node/builder.rs:468

        self.add_data_client_with_routing(name, factory, config, RoutingConfig::default())
    }

    /// Adds a data client factory with configuration and explicit routing.
    ///
    /// # Errors
    ///
    /// Returns an error if a client with the same name is already registered.
    pub fn add_data_client_with_routing(
        mut self,
        name: Option<String>,
        factory: Box<dyn DataClientFactory>,
        config: Box<dyn ClientConfig>,
        routing: RoutingConfig,
    ) -> anyhow::Result<Self> {
        let name = name.unwrap_or_else(|| factory.name().to_string());

        if self.data_client_factories.contains_key(&name) {
            anyhow::bail!("Data client '{name}' is already registered");
        }

        self.data_client_factories.insert(name.clone(), factory);
        self.data_client_configs.insert(name.clone(), config);
        self.data_client_routing.insert(name, routing);
        Ok(self)
    }

    /// Adds an execution client factory with configuration.
    ///
    /// Equivalent to [`Self::add_exec_client_with_routing`] with default (empty)
    /// routing.
    ///
    /// # Errors
    ///
    /// Returns an error if a client with the same name is already registered.
    pub fn add_exec_client(
        self,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Give each data client registration a unique explicit name: `add_data_client_with_routing(Some("my-unique-name".into()), ...)`.
  2. Audit your node builder code for duplicate `add_data_client` calls or double invocation.
  3. If intentionally re-registering, create a fresh `NodeBuilder` instead of reusing the populated one.

Example fix

// before: duplicate default names
.add_data_client(None, binance_factory, config)?
.add_data_client(None, binance_factory, config2)?

// after: unique explicit names
.add_data_client(None, binance_factory, config)?
.add_data_client_with_routing(Some("binance-2".into()), binance_factory, config2, routing)?
Defensive patterns

Strategy: validation

Validate before calling

let name = name.unwrap_or_else(|| factory.name().to_string());
if builder_has_data_client(&builder, &name) {
    return Err(anyhow::anyhow!("data client '{name}' already registered"));
}

Try / catch

match builder.add_data_client_with_routing(name, factory, config, routing) {
    Ok(b) => b,
    Err(e) if e.to_string().contains("already registered") => {
        // skip duplicate or use a unique name and retry
        builder
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `add_data_client(...)` / `add_data_client_with_routing(...)` twice with the same name (explicit name or the factory's default `factory.name()`), typically inside a node build function executed twice or an adapter registered twice.

Common situations: Duplicate adapter registration in the trading node config; two instances of the same data client configured without distinct names; building the builder twice while reusing the same builder instance.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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