nautechsystems/nautilus_trader · error · anyhow::Error

Disconnect the execution client before payload storage opera

Error message

Disconnect the execution client before payload storage operations

What it means

payload_operation_database() is the shared entry point for all payload storage maintenance operations (check/protect/rewrap/rollback). It enforces via anyhow::ensure! that the execution client is NOT connected, because these operations mutate the storage directly and concurrent use by a live client would race or corrupt data. If self.core.is_connected() is true, the operation is rejected.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:926

    /// succeeds and the unprotected database passes a full payload check.
    ///
    /// # Errors
    ///
    /// Returns an error if the client is connected, storage is not protected, required keys are
    /// unavailable, or any bounded rollback batch fails authentication.
    pub async fn rollback_payload_storage(&self, batch_size: usize) -> anyhow::Result<()> {
        let batch_size = validate_payload_operation_batch_size(batch_size)?;
        let database = self.payload_operation_database().await?;
        let keys = self
            .load_payload_keys()?
            .ok_or_else(|| anyhow::anyhow!("Payload rollback requires an active payload key"))?;
        database
            .rollback_execution_payload_storage(&keys, batch_size)
            .await
    }

    async fn payload_operation_database(&self) -> anyhow::Result<BlockchainCacheDatabase> {
        anyhow::ensure!(
            !self.core.is_connected(),
            "Disconnect the execution client before payload storage operations"
        );

        if let Some(database) = &self.cache.database {
            return Ok(database.clone());
        }
        let options = self
            .config
            .postgres_cache_database_config
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("No Postgres cache database is configured"))?;
        BlockchainCacheDatabase::connect(options.clone().into())
            .await
            .context("failed to connect to the execution database")
    }

    fn load_payload_keys(&self) -> anyhow::Result<Option<PayloadKeySet>> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Call client.disconnect() (or equivalent shutdown) before invoking any payload storage operation.
  2. Run payload maintenance in a separate process/mode where the client is constructed without connecting.
  3. Reconnect the client after the operation completes if continued trading is needed.

Example fix

// before
client.protect_payload_storage(1000).await?;
// after
client.disconnect().await?;
client.protect_payload_storage(1000).await?;
client.connect().await?;
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(!client.is_connected(), "disconnect the client before payload maintenance");
client.rewrap_payload_storage(batch_size).await?;

Try / catch

match client.protect_payload_storage(batch).await {
    Ok(()) => client.connect().await?,
    Err(e) if e.to_string().contains("Disconnect the execution client") => {
        client.disconnect().await?;
        client.protect_payload_storage(batch).await?;
        client.connect().await?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling check_payload_storage, protect_payload_storage, rewrap_payload_storage, or rollback_payload_storage while the execution client still holds an active connection.

Common situations: Maintenance scripts that connect the client first (to check health) and then immediately try protect/rewrap; long-lived live trading clients where an operator runs payload maintenance without disconnecting.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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