nautechsystems/nautilus_trader · error

Failed to query add_currency to database message handler: {e

Error message

Failed to query add_currency to database message handler: {e}

What it means

Thrown by `add_currency` when the `DatabaseQuery::AddCurrency` message cannot be sent over the mpsc channel to the database message-handler task, which means the receiver has been dropped. The currency is not persisted to the database.

Source

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

    }

    fn delete_account_event(&self, account_id: &AccountId, event_id: &str) -> anyhow::Result<()> {
        anyhow::bail!(
            "delete_account_event not implemented for PostgreSQL cache adapter: {account_id}, {event_id}"
        )
    }

    fn add(&self, key: String, value: Bytes) -> anyhow::Result<()> {
        let query = DatabaseQuery::Add(key, value.into());
        self.tx
            .send(query)
            .map_err(|e| anyhow::anyhow!("Failed to send query to database message handler: {e}"))
    }

    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}"
                )
            })

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the cache database adapter is running before seeding dependencies.
  2. Inspect receiver task logs for panics that dropped the channel.
  3. Recreate/reconnect the adapter and retry.
  4. Move currency seeding earlier in the workflow, before any shutdown of the writer.
Defensive patterns

Strategy: try-catch

Validate before calling

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

Try / catch

try:
    cache.add_currency(currency)
except RuntimeError as e:
    logger.error("Currency persistence failed (writer stopped): %s", e)

Prevention

When it happens

Trigger: Calling `add_currency` (via `py_add_currency` or `seed_order_event_dependencies`) after the database writer task has exited/been dropped, so `tx.send` returns a SendError.

Common situations: Seeding currencies during order-event persistence after the adapter was stopped; a panic in the handler thread; writing during process shutdown.

Related errors


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