nautechsystems/nautilus_trader · error · anyhow::Error

No durable store configured; refusing to persist execution…

Error message

No durable store configured; refusing to persist execution transaction

What it means

BlockchainCache.add_execution_transaction requires a configured durable database before persisting execution transaction records. When no database was provided to the cache, it refuses the write rather than silently dropping the record, since execution transactions are expected to be durable.

Solutions

  1. Configure a database on the BlockchainCache at construction so self.database is Some
  2. If memory-only mode is intended, guard the caller: skip persistence calls when the cache has no database
  3. Check the deployment config/env for the missing database URL and supply it
  4. Verify initialization code actually passes the database handle into the cache constructor

Example fix

// before
let cache = BlockchainCache::new(chain, None);
cache.add_execution_transaction(&hash, "swap", "pending", None).await?;
// after
let cache = BlockchainCache::new(chain, Some(database)); // durable store configured
cache.add_execution_transaction(&hash, "swap", "pending", None).await?;
Defensive patterns

Strategy: validation

Validate before calling

if cache.database.is_none() {
    eprintln!("cannot persist execution transaction: no durable store configured");
}

Type guard

fn has_durable_store(cache: &BlockchainCache) -> bool {
    cache.database.is_some()
}

Try / catch

match cache.add_execution_transaction(&hash, "swap", "pending", None).await {
    Err(e) if e.to_string().contains("No durable store configured") => {
        // buffer the record or surface a configuration error
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling add_execution_transaction(...) on a BlockchainCache constructed without a database (self.database is None), e.g. an in-memory cache configured without the database option.

Common situations: Deploying without the database connection string / database option set; a config file omitting the cache database section; intentionally running cache in memory-only mode but code paths still call persistence methods.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/blockchain/src/cache/mod.rs:176

    /// # Errors
    ///
    /// Returns an error if no database is configured or the database operation fails.
    #[expect(
        clippy::too_many_arguments,
        reason = "the parameters mirror the persisted execution transaction fields"
    )]
    pub async fn add_execution_transaction(
        &self,
        chain_id: u32,
        wallet_address: &str,
        nonce: u64,
        transaction_hash: &str,
        purpose: &str,
        status: &str,
        client_order_id: Option<&str>,
    ) -> anyhow::Result<()> {
        let database = self.database.as_ref().ok_or_else(|| {
            anyhow::anyhow!(
                "No durable store configured; refusing to persist execution transaction"
            )
        })?;

        database
            .add_execution_transaction(
                chain_id,
                wallet_address,
                nonce,
                transaction_hash,
                purpose,
                status,
                client_order_id,
            )
            .await
    }

    /// Migrates the execution transaction table and installs its signer and order uniqueness

View on GitHub (pinned to 18893faf8b)