nautechsystems/nautilus_trader · error

Failed to send delete position command: {e}

Error message

Failed to send delete position command: {e}

What it means

delete_position queues a Delete command for the position record itself via the internal command channel. This error means the send failed because the Redis writer task no longer holds a live receiver.

Source

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

        }

        Ok(())
    }

    /// Delete the given position from the database with full index cleanup.
    ///
    /// # Errors
    ///
    /// Returns an error if the command cannot be sent to the background task channel.
    pub fn delete_position(&self, position_id: &PositionId) -> anyhow::Result<()> {
        let position_id_bytes = Bytes::from(position_id.to_string());

        // Delete the position itself
        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(())

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the cache database task is running and reconnect if it was stopped.
  2. Avoid calling delete_position after node shutdown has begun.
  3. Find and fix the earlier failure (connection loss, panic) that ended the writer task.
  4. Restart the trading node or rebuild the RedisCache adapter and re-attempt the delete.
Defensive patterns

Strategy: try-catch

Try / catch

match cache.delete_position(&position_id) {
    Err(e) if e.to_string().contains("Failed to send delete position command") => {
        // writer task unavailable: reconnect or defer until restart
    }
    result => result?,
}

Prevention

When it happens

Trigger: Calling delete_position (or py_delete_position) after the background command-processing task has been dropped or shut down.

Common situations: Position cleanup during node shutdown, after a Redis outage terminated the writer task, or on a cache adapter whose command loop never ran.

Related errors


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