nautechsystems/nautilus_trader · error

Failed to send query add_instrument_close to database…

Error message

Failed to send query add_instrument_close to database message handler: {e}

What it means

Thrown by `add_instrument_close` when sending `DatabaseQuery::AddInstrumentClose` to the database message-handler task fails because the receiving end of the channel has been dropped. The instrument close is not persisted.

Solutions

  1. Keep the cache database adapter running until all writes complete.
  2. Check for panics in the message-handler task.
  3. Restart/reconnect the adapter and re-issue the write.
  4. Sequence shutdown so the cache is closed last.
Defensive patterns

Strategy: try-catch

Validate before calling

if not cache_db_adapter.is_running:
    raise RuntimeError("Cannot add_instrument_close: adapter not running")

Try / catch

try:
    cache.add_instrument_close(close)
except RuntimeError as e:
    logger.error("Instrument close persistence failed: %s", e)

Prevention

When it happens

Trigger: Calling `add_instrument_close` after the writer task shut down or its thread panicked, making `tx.send` return a SendError.

Common situations: Persisting instrument closes during teardown; a crashed writer task in a long-running session.

Related errors


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

Appendix: source

Thrown at crates/infrastructure/src/sql/cache.rs:931

    fn add_currency(&self, currency: &Currency) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddCurrency(*currency);
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to query add_currency to database message handler: {e}")
        })
    }

    fn add_instrument(&self, instrument: &InstrumentAny) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddInstrument(instrument.clone());
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query add_instrument to database message handler: {e}")
        })
    }

    fn add_instrument_close(&self, close: &InstrumentClose) -> anyhow::Result<()> {
        self.tx
            .send(DatabaseQuery::AddInstrumentClose(*close))
            .map_err(|e| {
                anyhow::anyhow!(
                    "Failed to send query add_instrument_close to database message handler: {e}"
                )
            })
    }

    fn add_synthetic(&self, _synthetic: &SyntheticInstrument) -> anyhow::Result<()> {
        todo!()
    }

    fn add_account(&self, account: &AccountAny) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddAccount(account_last_event(account)?, false);
        self.tx.send(query).map_err(|e| {
            anyhow::anyhow!("Failed to send query add_account to database message handler: {e}")
        })
    }

    fn add_order(&self, order: &OrderAny, client_id: Option<ClientId>) -> anyhow::Result<()> {
        let query = DatabaseQuery::AddOrder(order_initialized_event(order), client_id);

View on GitHub (pinned to 18893faf8b)