nautechsystems/nautilus_trader · error

Retained execution intent has an unsupported purpose

Error message

Retained execution intent has an unsupported purpose

What it means

Retained intents store their purpose as a string; during recovery the client parses it back into the TransactionPurpose enum. This error is thrown when the stored purpose string does not parse to a known variant, indicating the snapshot was written by an incompatible version or contains corrupt data.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:5342

            active_count <= 1,
            "Retained execution history has multiple active signer owners"
        );

        let mut nonce_owners = HashMap::new();
        let mut records = Vec::with_capacity(snapshot.intents.len());
        let finalized_headers = finalized_headers
            .iter()
            .map(durable_verified_header)
            .collect::<Vec<_>>();

        for intent in &snapshot.intents {
            anyhow::ensure!(
                intent.chain_id == self.chain.chain_id
                    && intent.wallet_address == self.config.wallet_address,
                "Retained execution intent belongs to another signer"
            );
            let purpose = TransactionPurpose::parse(&intent.purpose).ok_or_else(|| {
                anyhow::anyhow!("Retained execution intent has an unsupported purpose")
            })?;
            let hashes = hashes_by_intent
                .get(&intent.id)
                .map(Vec::as_slice)
                .unwrap_or_default();
            let current = hashes
                .iter()
                .copied()
                .filter(|hash| hash.current)
                .collect::<Vec<_>>();
            anyhow::ensure!(
                current.len() <= 1,
                "Retained execution intent {} has multiple current hashes",
                intent.id
            );
            let current = current.first().copied();
            let mut authenticated = HashMap::new();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Upgrade the client to the version that wrote the snapshot so all purpose strings parse
  2. Archive/migrate the snapshot: export, map old purpose strings to current variants, and rewrite the store
  3. Reset the execution snapshot to force a clean rebuild if the intents are all finalized anyway
Defensive patterns

Strategy: try-catch

Validate before calling

fn purposes_parseable(snapshot: &ExecutionSnapshot) -> Result<(), String> {
    for i in &snapshot.intents {
        if TransactionPurpose::parse(&i.purpose).is_none() {
            return Err(format!("intent {} has unknown purpose '{}'", i.id, i.purpose));
        }
    }
    Ok(())
}

Try / catch

match client.start_with_snapshot(snapshot) {
    Err(e) if e.to_string().contains("unsupported purpose") => { /* upgrade client or migrate/rewrite snapshot */ }
    other => other?,
}

Prevention

When it happens

Trigger: Loading a snapshot where intent.purpose is an unrecognized string (e.g. renamed enum variant, typo, or a purpose added by a newer version than the running client).

Common situations: Downgrading the client after a newer release introduced new TransactionPurpose variants; hand-editing snapshot files; corruption of the durable store.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/81e358b88610cb3b. Report an issue: GitHub.