nautechsystems/nautilus_trader · error · anyhow::Error
No durable store configured for execution reconciliation
Error message
No durable store configured for execution reconciliation
What it means
reconcile_unresolved_execution (crates/adapters/blockchain/src/execution/client.rs:907) fails closed when cache.database is None: crash recovery of in-flight execution requires the durable intent store, so reconciliation without it is refused rather than skipped. In the normal flow connect() guards this call with cache.has_database() (the store is attached only when postgres_cache_database_config is set), so hitting the error means the method ran against a store-less cache - a direct invocation, a reconfigured client, or a code path that bypassed connect().
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:909
Ok(SwapPlan {
order,
quote_currency,
pool,
instrument_id,
pool_address,
router: Address::from_str(&intent.transaction_to)?,
token_in,
token_out,
fee,
amount_in,
min_amount_out: U256::ZERO,
profiler_block: intent.created_block,
})
}
async fn reconcile_unresolved_execution(&self) -> anyhow::Result<()> {
let database = self.cache.database.clone().ok_or_else(|| {
anyhow::anyhow!("No durable store configured for execution reconciliation")
})?;
let wallet_address = self.wallet_address.to_string();
let Some(intent) = database
.get_active_execution_intent(self.chain.chain_id, &wallet_address)
.await?
else {
return Ok(());
};
anyhow::ensure!(
intent.schema_version == crate::execution::transaction::EXECUTION_SCHEMA_VERSION,
"Execution intent {} uses unsupported schema version {}",
intent.id,
intent.schema_version
);
if matches!(intent.status.as_str(), "prepared" | "signed") {
database
.mark_execution_intent_recoverable(intent.id)View on GitHub (pinned to 2114cf6f76)
Solutions
- Set BlockchainExecutionClientConfig::postgres_cache_database_config before constructing the client.
- Call connect() and let it drive reconciliation itself - it attaches the store and calls this method with the guard in place.
- Verify cache.has_database() is true before any manual reconciliation call.
- Check connect() logs for the "No Postgres cache database configured" warning to catch the misconfiguration early.
Example fix
// before
let config = BlockchainExecutionClientConfig {
postgres_cache_database_config: None,
..Default::default()
};
// client.reconcile_unresolved_execution() -> "No durable store configured for execution reconciliation"
// after
let config = BlockchainExecutionClientConfig {
postgres_cache_database_config: Some(postgres_connect_options),
..Default::default()
};
// connect() attaches the store and runs reconciliation guarded by has_database() Defensive patterns
Strategy: validation
Validate before calling
// Rust: reconciliation needs the durable store - verify before calling
anyhow::ensure!(
client.cache.has_database(),
"reconciliation requires postgres_cache_database_config"
); Type guard
fn is_no_durable_store_for_reconciliation(e: &anyhow::Error) -> bool {
e.to_string()
.contains("No durable store configured for execution reconciliation")
} Try / catch
match client.reconcile_unresolved_execution().await {
Ok(()) => {}
Err(e) if is_no_durable_store_for_reconciliation(&e) => {
// configuration defect: attach Postgres and reconnect; do not skip reconciliation
return Err(e.context("set postgres_cache_database_config before recovery"));
}
Err(e) => return Err(e),
} Prevention
- Let connect() own reconciliation - it guards with has_database() and attaches the store.
- Any custom recovery tooling must construct the client with Postgres options too.
- Assert has_database() in startup health checks for deployments that trade.
When it happens
Trigger: Invoking reconcile_unresolved_execution on a client whose config omitted postgres_cache_database_database style options (postgres_cache_database_config: None), so connect() never attached a store; calling reconciliation manually on a freshly constructed, unconnected client; config where Postgres options failed to parse and the field defaulted to None.
Common situations: Missing Postgres environment variables in recovery tooling; ops scripts constructing a client just to reconcile without wiring the durable store; deployments that previously ran without persistence now attempting reconciliation.
Related errors
- No durable store configured; refusing to persist execution t
- No durable store configured; refusing to submit a transactio
- No durable store configured; refusing to migrate execution t
- Persisted swap intent has no client order ID
- Persisted swap intent has no instrument ID
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/0f94fff5e85628db.
Report an issue: GitHub.