nautechsystems/nautilus_trader · error · anyhow::Error
Failed to inspect recoverable signed executions: {e}
Error message
Failed to inspect recoverable signed executions: {e} What it means
This wraps a SQLx failure from the query that inspects whether a signed execution is recoverable for a chain/wallet pair, ending in fetch_one (database.rs:7321). fetch_one additionally errors when the query returns zero rows, so besides genuine database failures, an empty result set (no nonce ledger / intent row for that chain + wallet) surfaces as this error.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:7321
.with_context(|| format!("Chain ID {chain_id} exceeds PostgreSQL INTEGER"))?;
sqlx::query_scalar::<_, bool>(
"
SELECT EXISTS (
SELECT 1
FROM execution_intent AS intent
JOIN execution_transaction_hash AS hash ON hash.intent_id = intent.id
WHERE intent.chain_id = $1
AND intent.wallet_address = $2
AND intent.status = 'recoverable'
AND (hash.raw_transaction IS NOT NULL OR hash.sealed_transaction IS NOT NULL)
)
",
)
.bind(chain_id_db)
.bind(wallet_address)
.fetch_one(&self.pool)
.await
.map_err(|e| anyhow::anyhow!("Failed to inspect recoverable signed executions: {e}"))
}
/// Loads all transaction hashes for an intent in insertion order.
///
/// # Errors
///
/// Returns an error if the query fails.
pub async fn get_execution_transaction_hashes(
&self,
intent_id: i64,
) -> anyhow::Result<Vec<ExecutionTransactionHashRow>> {
sqlx::query_as::<_, ExecutionTransactionHashRow>(
"
SELECT
id, intent_id, chain_id, transaction_hash, payload_expected,
raw_transaction, sealed_transaction, status,
block_number, block_hash, receipt_success, gas_used,
effective_gas_price, currentView on GitHub (pinned to 18893faf8b)
Solutions
- If the wrapped message indicates RowNotFound, first confirm a ledger/intent row exists for that chain_id + wallet_address (initialize it if the wallet is new).
- Read the wrapped {e} for driver-level causes; retry on transient connection/timeout errors.
- Run pending migrations to ensure the queried tables exist.
- Normalize the wallet address format (same case/encoding as stored) and verify chain_id matches the stored rows.
- Check Postgres logs if failures correlate with load or failover.
Example fix
// before: fetch_one that errors when no row exists
let state = sqlx::query(...).fetch_one(&pool).await.map_err(...)?;
// after: handle the empty case explicitly
let state = sqlx::query_as::<_, RecoverableState>(...).fetch_optional(&pool).await?;
let state = state.ok_or_else(|| anyhow!("no recoverable execution state for {wallet} on chain {chain_id}"))?; Defensive patterns
Strategy: try-catch
Validate before calling
let row_exists: Option<i32> = sqlx::query_scalar(
"SELECT 1 FROM execution_verification_nonce WHERE chain_id = $1 AND wallet_address = $2")
.bind(chain_id_db).bind(wallet).fetch_optional(&pool).await?;
anyhow::ensure!(row_exists.is_some(), "no recoverable-execution state for {wallet} on chain {chain_id}"); Type guard
fn is_row_not_found(e: &anyhow::Error) -> bool {
e.chain().any(|c| c.to_string().contains("no rows returned"))
} Try / catch
match inspect_result {
Err(e) if is_row_not_found(&e) => initialize_wallet_state(chain_id, wallet).await?,
Err(e) if is_transient(&e) => retry_with_backoff(...).await?,
other => other?,
} Prevention
- Initialize ledger/state rows when a wallet is first used so inspection never sees zero rows.
- Prefer fetch_optional in caller-side code to distinguish 'empty' from 'failed'.
- Normalize address format and chain_id before querying.
- Run migrations on every environment before deploying adapter updates.
When it happens
Trigger: The inspection query fails at the driver level (connection loss, timeout, undefined table after missed migration), or fetch_one receives 0 rows because no execution_verification_nonce/intent row exists yet for the given chain_id + wallet_address.
Common situations: Querying recovery state for a wallet that has never had a signed execution; pointing the adapter at a database where migrations were not applied; transient connectivity loss; passing a chain_id or wallet address that differs from how it was stored (e.g. checksummed vs lowercase).
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- Failed to load block timestamps: {e}
- Failed to number verified action evidence: {e}
- Failed to load execution transaction hashes: {e}
- Failed to load bars: {e}
- Failed to load signals: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5d1c25d13e7f2dd3.
Report an issue: GitHub.