nautechsystems/nautilus_trader · error · anyhow::Error
Active execution intent {} has no nonce
Error message
Active execution intent {} has no nonce What it means
An active execution_intent row has nonce = NULL when reconciliation needs it to track the in-flight transaction. The nonce is assigned by assign_execution_intent_nonce() during prepare_and_sign, before signing; an active intent that reached broadcast/pending status must therefore always carry one. NULL means the intent was persisted but the nonce-assignment write never committed, or the row was changed outside the client.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:942
if matches!(intent.status.as_str(), "prepared" | "signed") {
database
.mark_execution_intent_recoverable(intent.id)
.await?;
release_preparing_slot(&self.in_flight);
return Ok(());
}
let purpose = TransactionPurpose::parse(&intent.purpose).ok_or_else(|| {
anyhow::anyhow!(
"Execution intent {} has unknown purpose {}",
intent.id,
intent.purpose
)
})?;
let nonce = intent
.nonce
.ok_or_else(|| anyhow::anyhow!("Active execution intent {} has no nonce", intent.id))?;
let hashes = database.get_execution_transaction_hashes(intent.id).await?;
let current = current_execution_hash(intent.id, &hashes)?;
let tx_hash = B256::from_str(¤t.transaction_hash).with_context(|| {
format!(
"Execution intent {} has invalid transaction hash {}",
intent.id, current.transaction_hash
)
})?;
*self.in_flight.lock().expect("in-flight mutex poisoned") =
Some(InFlightSlot::AwaitingFinality(InFlightTransaction {
intent_id: intent.id,
nonce,
tx_hash,
purpose,
}));
let plan = if purpose == TransactionPurpose::Swap {
Some(self.restore_swap_plan(&intent)?)View on GitHub (pinned to 2114cf6f76)
Solutions
- Inspect the row: SELECT id, status, nonce FROM execution_intent WHERE active AND nonce IS NULL;
- If status is 'prepared' or 'signed', the reconciler would have handled it, so for NULL-nonce rows past those statuses the row is invalid: verify on-chain (eth_getTransactionByHash of its current hash) whether anything was broadcast
- If nothing was broadcast, mark the intent inactive (active = FALSE) so startup proceeds, and let the slot logic re-claim cleanly
- If a transaction did land, repair the nonce from the on-chain transaction and let reconciliation finish
Example fix
-- before: active intent without nonce blocks connect() SELECT id, status, nonce FROM execution_intent WHERE active AND nonce IS NULL; -- after: confirm no on-chain tx, then retire the malformed intent UPDATE execution_intent SET active = FALSE WHERE id = 42 AND nonce IS NULL;
Defensive patterns
Strategy: validation
Validate before calling
-- Active intents past the signed stage must carry a nonce
SELECT id, status, nonce
FROM execution_intent
WHERE active
AND nonce IS NULL
AND status NOT IN ('prepared', 'signed');
-- Zero rows expected; otherwise reconcile or retire the row before connect(). Try / catch
try:
client.connect()
except Exception as e:
if 'has no nonce' in str(e):
# check execution_transaction_hash + on-chain state, then repair or deactivate the intent
...
raise Prevention
- Let the client own nonce assignment; never reset nonces or intent rows while a trader is running
- After a crash, reconnect the same wallet+store so reconciliation completes partial writes
When it happens
Trigger: reconcile_unresolved_execution() loads an active intent (active = TRUE) whose status is past prepared/signed (e.g. 'pending' or 'included') and whose nonce column is NULL: a partially written row from a crashed run between INSERT and nonce assignment, manual row edits, or a database restored inconsistently.
Common situations: Process killed or Postgres failover exactly between intent insert and nonce assignment; DBA manually resetting intents; a store shared between two wallet configurations where one tool wrote incomplete rows.
Related errors
- Execution intent {} has unknown purpose {}
- Execution intent {intent_id} has no current hash
- Execution intent {intent_id} has more than one current hash
- Execution transaction hash {transaction_hash} was not found
- Replacement hash {transaction_hash} conflicts with another i
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/026d690c607c1d94.
Report an issue: GitHub.