nautechsystems/nautilus_trader · error · anyhow::Error
Execution intent {intent_id} has no current hash
Error message
Execution intent {intent_id} has no current hash What it means
current_execution_hash() filters a reconciliation-loaded intent's transaction-hash history for the row flagged current = TRUE and found none. Every intent past the prepared/signed stage must have exactly one current hash (the hash reconciliation should track), so the table invariant is broken and the intent cannot be replayed.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1832
stable_head.hash == head.hash,
"Canonical head changed during signer-nonce replacement scan"
);
Ok(found)
}
fn release_slot(&self) {
*self.in_flight.lock().expect("in-flight mutex poisoned") = None;
}
}
fn current_execution_hash(
intent_id: i64,
hashes: &[ExecutionTransactionHashRow],
) -> anyhow::Result<&ExecutionTransactionHashRow> {
let mut current = hashes.iter().filter(|row| row.current);
let row = current
.next()
.ok_or_else(|| anyhow::anyhow!("Execution intent {intent_id} has no current hash"))?;
anyhow::ensure!(
current.next().is_none(),
"Execution intent {intent_id} has more than one current hash"
);
Ok(row)
}
/// Polls for the receipt of a broadcast transaction until it exists or the poll bound
/// is exhausted. A `null` receipt result is a legitimate pending response.
#[cfg(test)]
async fn poll_for_receipt(
http_rpc_client: &BlockchainHttpRpcClient,
tx_hash: &B256,
max_polls: u32,
interval: Duration,
) -> anyhow::Result<Option<RpcTransactionReceipt>> {
let mut last_error = None;
let mut observed_pending = false;View on GitHub (pinned to 2114cf6f76)
Solutions
- Inspect the rows: SELECT id, transaction_hash, status, current FROM execution_transaction_hash WHERE intent_id = <id> ORDER BY id;
- If rows exist but none is current, set current = TRUE on the newest row matching the intent's on-chain reality (verify with eth_getTransactionByHash)
- If no rows exist and nothing was broadcast (intent stuck pre-broadcast), retire the intent (active = FALSE) so reconciliation proceeds
- Restore the 'one current hash per intent' invariant and prevent out-of-band edits to these tables
Example fix
-- before: all rows have current = FALSE SELECT id, transaction_hash, current FROM execution_transaction_hash WHERE intent_id = 42; -- (3 rows, all current = FALSE) -- after: flag the newest verified row as current UPDATE execution_transaction_hash SET current = TRUE WHERE id = (SELECT max(id) FROM execution_transaction_hash WHERE intent_id = 42);
Defensive patterns
Strategy: try-catch
Validate before calling
-- Invariant check before startup: every active intent past signing has exactly one current hash
SELECT i.id
FROM execution_intent i
JOIN execution_transaction_hash h ON h.intent_id = i.id
WHERE i.active AND i.status NOT IN ('prepared', 'signed')
GROUP BY i.id
HAVING count(*) FILTER (WHERE h.current) <> 1;
-- Zero rows expected; otherwise repair before connect(). Try / catch
try:
client.connect()
except Exception as e:
if 'has no current hash' in str(e):
# inspect execution_transaction_hash for the intent, verify hashes on-chain,
# flag the correct row current = TRUE (or deactivate a never-broadcast intent), then retry
...
raise Prevention
- Never delete rows from execution_transaction_hash; the client manages the current flag through its replace flow
- Run the single-current-hash invariant query as part of pre-startup DB checks
When it happens
Trigger: reconcile_unresolved_execution loading an intent whose execution_transaction_hash rows either are empty or all have current = FALSE: partial writes if the add_execution_transaction_hash commit was lost, manual row deletion, or external tools clearing flags.
Common situations: DB crash between intent activation and hash insert; DBAs trimming the hash-history table; a restored-from-backup database where later rows were lost.
Related errors
- Execution intent {intent_id} has more than one current hash
- Execution intent {} has unknown purpose {}
- Active execution intent {} has no nonce
- Execution transaction {transaction_hash} conflicts with its
- Execution transaction hash {transaction_hash} was not found
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/a9295e08391d8928.
Report an issue: GitHub.