nautechsystems/nautilus_trader · error

Cannot set cache database while node is running, set it befo

Error message

Cannot set cache database while node is running, set it before running the node

What it means

set_cache_database (crates/live/src/node/mod.rs:2480) swaps the backing CacheDatabaseAdapter (PostgreSQL, Redis, ...) on the kernel's cache. It is only legal while the node is NodeState::Idle, because the database adapter is wired into the cache before startup; once the node has left Idle the adapter is live and replacing it mid-run would drop or corrupt persisted state.

Source

Thrown at crates/live/src/node/mod.rs:2485

    pub fn is_running(&self) -> bool {
        self.state().is_running()
    }

    /// Sets the cache database adapter for persistence.
    ///
    /// This allows setting a database adapter (e.g., PostgreSQL, Redis) after the node
    /// is built but before it starts running. The database adapter is used to persist
    /// cache data for recovery and state management.
    ///
    /// # Errors
    ///
    /// Returns an error if the node is already running.
    pub fn set_cache_database(
        &mut self,
        database: Box<dyn CacheDatabaseAdapter>,
    ) -> anyhow::Result<()> {
        if self.state() != NodeState::Idle {
            anyhow::bail!(
                "Cannot set cache database while node is running, set it before running the node"
            );
        }

        self.kernel.cache().borrow_mut().set_database(database);
        Ok(())
    }

    /// Returns the execution manager.
    #[must_use]
    pub fn exec_manager(&self) -> &ExecutionManager {
        &self.exec_manager
    }

    /// Returns a mutable reference to the execution manager.
    #[must_use]
    pub fn exec_manager_mut(&mut self) -> &mut ExecutionManager {
        &mut self.exec_manager

View on GitHub (pinned to 2114cf6f76)

Solutions

  1. Move set_cache_database into the setup phase, immediately after building the node and before run().
  2. Prefer configuring the cache database through the node builder/config so the ordering cannot be wrong.
  3. Build a new node instance for each run session instead of reconfiguring a used one.

Example fix

// before
node.run().await?;                 // node leaves Idle
node.set_cache_database(pg)?;      // bails

// after
node.set_cache_database(pg)?;      // while Idle
node.run().await?;
Defensive patterns

Strategy: validation

Validate before calling

if node.state() == NodeState::Idle {
    node.set_cache_database(Box::new(pg_adapter))?;
} else {
    anyhow::bail!("configure the cache database before running the node");
}

Try / catch

if let Err(e) = node.set_cache_database(adapter) {
    if e.to_string().contains("while node is running") {
        log::error!("stop the node, reconfigure, and start a fresh instance");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Calling node.set_cache_database(adapter) after run()/run_with_mode() has started, during shutdown, or on a node whose state is anything other than Idle.

Common situations: Configuration code placed inside on_start or after the run call; reusing one node instance and attempting to reconfigure it for a second run; hosted apps that connect the database lazily after the node began running.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21). Data as JSON: /api/errors/5b488edad7251c63. Report an issue: GitHub.