nautechsystems/nautilus_trader · error

Controller execute endpoint '{}' not registered

Error message

Controller execute endpoint '{}' not registered

What it means

Controller::send dispatches a ControllerCommand to a handler looked up in the controller's endpoint map. If the requested endpoint string is not registered, no handler exists to run, so send bails with the endpoint name. It protects against silently dropping commands sent to mistyped or unregistered endpoints.

Source

Thrown at crates/system/src/controller.rs:67

    /// Sends a controller command to the registered controller endpoint.
    ///
    /// # Errors
    ///
    /// Returns an error if the controller execute endpoint is not registered.
    pub fn send(command: &ControllerCommand) -> anyhow::Result<()> {
        let endpoint = Self::execute_endpoint();
        let handler = {
            let msgbus = get_message_bus();
            msgbus
                .borrow_mut()
                .endpoint_map::<ControllerCommand>()
                .get(endpoint)
                .cloned()
        };

        let Some(handler) = handler else {
            anyhow::bail!(
                "Controller execute endpoint '{}' not registered",
                endpoint.as_str()
            );
        };

        handler.handle(command);
        Ok(())
    }

    /// Executes a controller command against the underlying trader.
    ///
    /// # Errors
    ///
    /// Returns an error if the requested lifecycle operation fails.
    pub fn execute(&mut self, command: ControllerCommand) -> anyhow::Result<()> {
        match command {
            ControllerCommand::CreateActor(command) => self
                .create_actor_from_config(&command.actor_config, command.start)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. List the controller's registered endpoints and confirm the exact endpoint string you are sending
  2. Fix the endpoint name (exact match, case-sensitive)
  3. Ensure registration (register_endpoint / controller setup) completes before sending commands
  4. If the endpoint requires Python actors (e.g. CreateActor for importable configs), use the Python-enabled build/controller

Example fix

// before
controller.send("create_actor".into(), command)?;
// after: use the registered endpoint name
controller.send("CreateActor".into(), command)?;
Defensive patterns

Strategy: validation

Validate before calling

// Check the endpoint exists before sending
// (endpoint_map is internal; maintain the set of known endpoints in caller code)
let known_endpoints = ["CreateActor", "CreateStrategy", "Start", "Stop"];
anyhow::ensure!(
    known_endpoints.contains(&endpoint.as_str()),
    "unknown controller endpoint {endpoint}"
);

Try / catch

match controller.send(endpoint.clone(), command) {
    Err(e) if e.to_string().contains("not registered") => {
        log::warn!("endpoint {endpoint} unknown; did registration complete?");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling controller.send(endpoint, command) (or issuing a control command over the bus) with an endpoint name that was never registered via register_endpoint — e.g. a typo, or sending a command before registration ran.

Common situations: Typo in the endpoint string; sending commands before the controller finished registering its handlers; a renamed endpoint after an upgrade; sending an endpoint that only exists in the Python controller from the Rust one.

Related errors


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