nautechsystems/nautilus_trader · error

Failed to send delete position index command: {e}

Error message

Failed to send delete position index command: {e}

What it means

After deleting the position record, delete_position removes the position id from set indexes (positions, open positions, closed positions). This error indicates the channel send for one of those index delete commands failed because the writer task's receiver is gone.

Source

Thrown at crates/infrastructure/src/redis/cache.rs:619

        let key = format!("{POSITIONS}{REDIS_DELIMITER}{position_id}");
        let op = DatabaseCommand::new(DatabaseOperation::Delete, key, None);
        self.tx
            .send(op)
            .map_err(|e| anyhow::anyhow!("Failed to send delete position command: {e}"))?;

        // Delete from all position indexes
        let index_keys = [
            INDEX_POSITIONS,
            INDEX_POSITIONS_OPEN,
            INDEX_POSITIONS_CLOSED,
        ];

        for index_key in &index_keys {
            let key = (*index_key).to_string();
            let payload = vec![position_id_bytes.clone()];
            let op = DatabaseCommand::new(DatabaseOperation::Delete, key, Some(payload));
            self.tx.send(op).map_err(|e| {
                anyhow::anyhow!("Failed to send delete position index command: {e}")
            })?;
        }

        Ok(())
    }

    /// Delete the given account event from the database.
    ///
    /// # Errors
    ///
    /// Returns an error if the command cannot be sent to the background task channel.
    pub fn delete_account_event(
        &self,
        account_id: &AccountId,
        event_id: &str,
    ) -> anyhow::Result<()> {
        log::warn!(
            "Deleting account events currently a no-op (pending redesign), {account_id}: {event_id}"

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Restore the writer task / connection and retry delete_position so indexes are cleaned.
  2. Keep all cache mutations inside the active node lifecycle.
  3. Diagnose the original cause of the writer task exit from earlier logs.
  4. Check Redis position index sets for stale ids if a partial delete occurred.
Defensive patterns

Strategy: retry

Try / catch

if let Err(e) = cache.delete_position(&position_id) {
    if e.to_string().contains("delete position index command") {
        // reconnect cache and re-run delete_position to finish index cleanup
    }
}

Prevention

When it happens

Trigger: Calling delete_position with a dead command channel — raised during the index-cleanup loop after the position delete was queued.

Common situations: Shutdown-time cleanup, writer task death from Redis connectivity loss, or misuse of a cache adapter outside the live node lifecycle.

Related errors


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