nautechsystems/nautilus_trader · error · anyhow::Error

Live runner system command channel is unavailable

Error message

Live runner system command channel is unavailable

What it means

DataActor::reconnect_socket requires a live runner system command channel to forward a ReconnectSocket command to the trader. The actor tries `try_get_system_command_sender()`; when it returns None there is no registered system command sender, so the reconnect request cannot be delivered. This only works when the actor runs inside a live (or wired test) runner that has installed the system command channel.

Source

Thrown at crates/common/src/actor/data_actor.rs:5760

    /// Sends a fire-and-observe reconnect command.
    ///
    /// # Errors
    ///
    /// Returns an error if the actor is not registered, the endpoint label is invalid, the live
    /// runner is unavailable, or the command channel is closed.
    #[cfg(feature = "live")]
    pub fn reconnect_socket(&self, client_id: ClientId, endpoint: &str) -> anyhow::Result<()> {
        let endpoint = socket_endpoint(endpoint)?;

        if !self.is_properly_registered() {
            anyhow::bail!(
                "Actor {} has not been registered with a Trader",
                self.actor_id
            );
        }

        let sender = try_get_system_command_sender()
            .ok_or_else(|| anyhow::anyhow!("Live runner system command channel is unavailable"))?;
        let trader_id = self
            .trader_id
            .ok_or_else(|| anyhow::anyhow!("Actor {} has no trader ID", self.actor_id))?;
        let command = ReconnectSocket::new(trader_id, client_id, endpoint, self.timestamp_ns());
        sender
            .send(SystemCommand::ReconnectSocket(command))
            .map_err(|_| anyhow::anyhow!("Live runner system command channel is closed"))?;
        Ok(())
    }

    #[cfg(test)]
    pub fn quote_handler_count(&self) -> usize {
        self.quote_handlers.len()
    }

    #[cfg(test)]
    pub fn trade_handler_count(&self) -> usize {
        self.trade_handlers.len()

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Run the actor inside a live node (TradingNode/LiveRunner) so the system command channel is registered before the actor starts.
  2. Ensure the actor is started only after the live runner has initialized its system command sender (check node startup ordering).
  3. In tests or backtests, either install a mock system command sender or avoid calling reconnect_socket.
  4. Guard calls: check that the actor is executing in a live context before requesting a socket reconnect.

Example fix

// before
actor.reconnect_socket(client_id, endpoint)?; // panics/errors in backtest

// after
if is_live_context() {
    actor.reconnect_socket(client_id, endpoint)?;
} else {
    tracing::warn!("reconnect_socket requires a live runner; skipping");
}
Defensive patterns

Strategy: fallback

Validate before calling

// Rust
if try_get_system_command_sender().is_none() {
    tracing::warn!("no system command channel; skipping socket reconnect");
    return Ok(());
}

Type guard

fn has_system_command_channel() -> bool { try_get_system_command_sender().is_some() }

Try / catch

match actor.reconnect_socket(client_id, endpoint) {
    Ok(()) => {},
    Err(e) if e.to_string().contains("system command channel is unavailable") => {
        tracing::warn!("reconnect unavailable outside live runner: {e}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling DataActor's reconnect_socket (which builds a ReconnectSocket command for a client_id/endpoint) when no system command sender is registered via try_get_system_command_sender — e.g. the actor runs under a backtest or standalone context, or the live runner has not yet set up its system command channel.

Common situations: Running an actor that requests socket reconnection outside a LiveNodeInstance (backtest engine, isolated actor test); calling reconnect before the live runner finishes wiring its command channels; custom harnesses that register the actor with a Trader but never install the system command sender.

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/11e14a77bacd62e5. Report an issue: GitHub.