nautechsystems/nautilus_trader · critical · anyhow::Error

Execution payload storage is marked ready without its write

Error message

Execution payload storage is marked ready without its write fence or constraint

What it means

Even though the state row says operation='ready', the expected database protection infrastructure — the write fence and/or the constraint guarding execution payload tables — is absent. The code refuses to trust a 'ready' marker without the actual enforcement objects in place.

Source

Thrown at crates/adapters/blockchain/src/cache/database.rs:5081

            "SELECT deployment_id, protocol_version, operation, active_key_id \
             FROM execution_payload_state WHERE component = 'signed_transactions' FOR SHARE",
        )
        .fetch_optional(&mut *transaction)
        .await
        .context("failed to lock execution payload state")?
        .ok_or_else(|| anyhow::anyhow!("Execution payload state is missing"))?;
        let state = execution_payload_state_from_row(&state_row)?;
        validate_execution_payload_state(&state, keys)?;
        anyhow::ensure!(
            state.operation == "ready",
            "Execution payload storage is not ready"
        );
        let (payload_fence, payload_constraint) =
            sqlx::query_as::<_, (bool, bool)>(EXECUTION_PAYLOAD_INFRASTRUCTURE_QUERY)
                .fetch_one(&mut *transaction)
                .await
                .context("failed to inspect execution payload protection infrastructure")?;
        anyhow::ensure!(
            payload_fence && payload_constraint,
            "Execution payload storage is marked ready without its write fence or constraint"
        );
        validate_execution_payload_key_inventory(&mut transaction, keys).await?;
        transaction
            .commit()
            .await
            .context("failed to complete execution payload validation")?;
        Ok(())
    }

    pub(crate) async fn check_execution_payload_storage(
        &self,
        keys: Option<&PayloadKeySet>,
        policy: Option<PayloadPolicy>,
        batch_size: i64,
    ) -> anyhow::Result<ExecutionPayloadCheck> {
        let (check, transaction) = self

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Re-run the migration/setup step that creates the write fence and constraint
  2. Re-add the missing constraint or trigger per the schema definitions in the codebase
  3. Restore schema from a consistent backup
  4. Audit who/what dropped the infrastructure before re-marking ready
Defensive patterns

Strategy: validation

Validate before calling

let (fence, constraint): (bool, bool) = sqlx::query_as(EXECUTION_PAYLOAD_INFRASTRUCTURE_QUERY).fetch_one(&mut conn).await?;
if !(fence && constraint) { reapply_infrastructure(&mut conn).await?; }

Prevention

When it happens

Trigger: State marked ready but a trigger/constraint was dropped manually; migration marked ready then infrastructure was removed; restoring a backup that contains the state row but not the constraint/trigger definitions.

Common situations: Schema drift from manual DB surgery; partial restore from backups; DB migrations from other tooling dropping constraints.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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