nautechsystems/nautilus_trader · error

Cannot exit market for strategy {strategy_id}: control endpo

Error message

Cannot exit market for strategy {strategy_id}: control endpoint '{}' not registered

What it means

The trader's strategy_command_handler looks up a registered control endpoint for the given strategy via endpoint_map and bails when no handler is registered under that endpoint name. This means commands like 'exit market' cannot be routed to the strategy because it never registered a handler for that endpoint string.

Source

Thrown at crates/system/src/trader.rs:1402

        &self,
        strategy_id: StrategyId,
    ) -> anyhow::Result<TypedHandler<StrategyCommand>> {
        if !self.strategy_ids.contains(&strategy_id) {
            anyhow::bail!("Cannot market exit strategy, {strategy_id} not found");
        }

        let endpoint = strategy_control_endpoint(strategy_id);
        let handler = {
            let msgbus = get_message_bus();
            msgbus
                .borrow_mut()
                .endpoint_map::<StrategyCommand>()
                .get(endpoint)
                .cloned()
        };

        let Some(handler) = handler else {
            anyhow::bail!(
                "Cannot exit market for strategy {strategy_id}: control endpoint '{}' not registered",
                endpoint.as_str()
            );
        };

        Ok(handler)
    }

    /// Removes the strategy with the given `strategy_id`.
    ///
    /// Will stop the strategy first if it is currently running. Disposes the strategy
    /// and removes it from the trader's tracking along with its event subscriptions.
    ///
    /// # Errors
    ///
    /// Returns an error if the strategy is not registered, the cache is already borrowed, or
    /// disposal fails. A cache borrow failure preserves the strategy registration and its external
    /// order claims. A failed disposal keeps the strategy registered and tracked, and leaves it

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the strategy registers the control endpoint (endpoint_map) with the exact name being requested before commands are sent
  2. Check for typos or case differences in the endpoint string between caller and registration
  3. Ensure the strategy is still running/registered in the trader when the command is sent
  4. Add logging of the registered endpoint keys to compare against the requested endpoint

Example fix

// before: handler assumes endpoint exists
trader.command_strategy(strategy_id, endpoint, cmd)?;
// after: register endpoint on strategy start
fn on_start(&mut self) -> anyhow::Result<()> {
    self.register_endpoint("exit_market", Self::handle_exit_market);
    Ok(())
}
Defensive patterns

Strategy: validation

Validate before calling

if !trader.has_endpoint(&strategy_id, &endpoint) { return Err(anyhow!("endpoint {} not registered", endpoint.as_str())); }

Type guard

fn is_endpoint_registered(trader: &Trader, id: &StrategyId, ep: &Endpoint) -> bool { trader.has_endpoint(id, ep) }

Prevention

When it happens

Trigger: Calling a trader command path (e.g. exit-market style commands) with an `endpoint` whose handler was never registered by the strategy, the strategy being removed before the command arrives, or an endpoint name typo/mismatch between caller and strategy registration.

Common situations: Sending control commands to a strategy that hasn't started or registered its command endpoint; a renamed or refactored endpoint string on the strategy side while callers still use the old name; strategy was already removed/retired.

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/35e60e4bdfcb027b. Report an issue: GitHub.