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
- Call client.disconnect() (or equivalent shutdown) before invoking any payload storage operation.
- Run payload maintenance in a separate process/mode where the client is constructed without connecting.
- 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
- Run payload maintenance in a dedicated maintenance mode/process.
- Always disconnect before check/protect/rewrap/rollback.
- Automate: disconnect -> operate -> reconnect in one script.
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
- dYdX WebSocket stream task is already registered
- Global logging sender was already published
- default client already registered
- Cannot add components in current state: {}
- Cannot add execution algorithms in current state: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c645ba379a13a721.
Report an issue: GitHub.