nautechsystems/nautilus_trader · error
Retained signed intent {} has no current hash
Error message
Retained signed intent {} has no current hash What it means
During execution-verification state migration, the client replays each retained signed intent and requires a `current` transaction record (the current hash/attempt) to be present. This error is thrown when an active, signed intent has a nonce but its `current` option is None, meaning the persisted state is missing the hash of the transaction the signature was produced for. The library throws it because it cannot verify or migrate a signed intent without knowing which transaction hash it refers to, so it fails loudly instead of silently dropping on-chain state.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:5457
nonce: None,
transaction_hash: None,
terminal_status: None,
block_number: None,
block_hash: None,
receipt_success: None,
gas_used: None,
effective_gas_price: None,
recover_prepared: true,
decisions: vec![base_decision],
});
continue;
}
let nonce = intent.nonce.ok_or_else(|| {
anyhow::anyhow!("Retained signed intent {} has no nonce", intent.id)
})?;
let current = current.ok_or_else(|| {
anyhow::anyhow!("Retained signed intent {} has no current hash", intent.id)
})?;
let raw_transaction = authenticated.get(¤t.id).ok_or_else(|| {
anyhow::anyhow!(
"Retained signed intent {} has no authenticated current payload",
intent.id
)
})?;
if intent.active && nonce == next_canonical_nonce {
anyhow::ensure!(
!matches!(intent.status.as_str(), "finalized" | "reverted"),
"Active terminal intent conflicts with the canonical nonce ledger"
);
records.push(ExecutionVerificationMigrationRecord {
intent_id: intent.id,
nonce: Some(nonce),
transaction_hash: Some(current.transaction_hash.clone()),
terminal_status: None,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the persisted execution state for the intent id reported in the message and restore the missing current transaction record from a complete backup.
- Re-run state persistence from a consistent snapshot: stop the node, restore the latest intact state file/DB, and restart so migration sees the full intent+transaction pair.
- If the intent was never broadcast and its signature is unusable, remove or mark the intent as `recoverable`/`dropped` in the state store (which the migration path allows for nonterminal intents) before restarting.
- Check that you are not mixing state produced by different adapter versions; upgrade/downgrade consistently so the `current` hash field is always populated.
Example fix
// before (corrupt state row: intent persisted without current transaction)
{"id": "intent-42", "active": true, "nonce": 7} // no current hash
// after (complete record restored from backup)
{"id": "intent-42", "active": true, "nonce": 7, "current": {"id": "tx-9", "transaction_hash": "0xabc..."}} Defensive patterns
Strategy: validation
Validate before calling
fn validate_signed_intent(intent: &Intent, current: Option<&TxRecord>) -> Result<(), String> {
if intent.active && intent.nonce.is_some() && current.is_none() {
return Err(format!("intent {} is signed but missing current hash", intent.id));
}
Ok(())
} Type guard
fn has_current(intent: &Intent) -> bool {
intent.active && intent.nonce.is_some() && intent.current.is_some()
} Prevention
- Write intent records and their current-transaction rows atomically in one store transaction.
- Never hand-edit or partially copy the execution state store between environments.
- Back up state only at quiescent points (no in-flight intents).
- Version-check state schema before loading state saved by a different adapter release.
When it happens
Trigger: Raised by the migration routine in `client.rs` (`ok_or_else` on `current.ok_or_else(...)`) when iterating retained intents where: intent.active is true, intent.nonce is Some, but the `current` transaction record for the intent is absent from the loaded persistence snapshot — e.g. a partially-written or hand-edited state store, a truncated write that stored the intent but not its current transaction row, or deserializing state saved by a version that did not persist the current hash.
Common situations: Crash or kill between persisting the intent and its transaction hash; restoring state from an old backup or downgraded node against a newer state schema; manual tampering with the execution state DB; copying intent rows without their joined transaction rows between environments.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Retained signed intent {} has no authenticated current paylo
- Missing data in CollectProtocol event log
- Missing data in SetFeeProtocol event log
- Missing data in flash event log
- No durable store configured; refusing to submit a {} transac
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ca88b8dda6cb4aa7.
Report an issue: GitHub.