nautechsystems/nautilus_trader · error · anyhow::Error
Persisted swap intent has no pool address
Error message
Persisted swap intent has no pool address
What it means
restore_swap_plan (crates/adapters/blockchain/src/execution/client.rs:863) parses the persisted swap intent's pool_address column; a NULL value aborts reconciliation with this error. The pool address is mandatory on swap intents - it identifies the Uniswap-V3-style pool the swap routed through, and is cross-checked next against the pool resolved for the instrument. NULL therefore means incomplete durable state (legacy row, torn write, or manual edit), never a legitimate swap record.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:863
anyhow::ensure!(
intent.trader_id.as_deref() == Some(order.trader_id().as_str()),
"Persisted swap trader does not match restored order"
);
anyhow::ensure!(
intent.strategy_id.as_deref() == Some(order.strategy_id().as_str()),
"Persisted swap strategy does not match restored order"
);
anyhow::ensure!(
intent.account_id.as_deref() == Some(self.core.account_id.as_str()),
"Persisted swap account does not match execution client account"
);
let pool = self.resolve_pool(&instrument_id)?;
let pool_address = Address::from_str(
intent
.pool_address
.as_deref()
.ok_or_else(|| anyhow::anyhow!("Persisted swap intent has no pool address"))?,
)?;
anyhow::ensure!(
pool.address == pool_address,
"Persisted pool {pool_address} does not match restored pool {}",
pool.address
);
let amount_in = U256::from_str(
intent
.amount_in
.as_deref()
.ok_or_else(|| anyhow::anyhow!("Persisted swap intent has no input amount"))?,
)?;
let fee = U24::try_from(
pool.fee
.ok_or_else(|| anyhow::anyhow!("Restored pool {instrument_id} has no fee"))?,
)?;
let quote_token = pool.get_quote_token();
let quote_currency = Currency::new_checked(View on GitHub (pinned to 2114cf6f76)
Solutions
- Inspect the row: SELECT id, status, pool_address FROM execution_intent WHERE id = <id>.
- Verify the transaction outcome on-chain, then mark the intent resolved or recoverable so reconciliation proceeds.
- Audit sibling columns (amount_in, client_order_id, instrument_id) in the same row for NULLs.
- Ensure the current writer version always persists pool_address for swap intents.
Defensive patterns
Strategy: try-catch
Validate before calling
-- Pre-flight: active swap intents missing the pool address
SELECT id, status
FROM execution_intent
WHERE status IN ('prepared', 'signed', 'submitted')
AND purpose = 'swap'
AND pool_address IS NULL; Type guard
fn is_missing_pool_address(e: &anyhow::Error) -> bool {
e.to_string().contains("Persisted swap intent has no pool address")
} Try / catch
if let Err(e) = client.connect().await {
if is_missing_pool_address(&e) {
// incomplete durable row: verify on-chain, repair/resolve the intent, then reconnect
log::error!("swap intent lacks pool address: {e}");
}
return Err(e);
} Prevention
- Audit active intents for NULL routing columns before upgrades.
- Backfill missing pool addresses from on-chain swap events when preserving history.
- Ensure the writer always persists pool_address for swap intents.
When it happens
Trigger: An active swap intent row with NULL pool_address encountered during connect()-time reconciliation; rows written before pool_address persistence was enforced; SQL edits or ETL that nulled the column.
Common situations: Schema upgrades carrying old rows forward; restored backups from older versions; manual data surgery on intent tables.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Persisted swap intent has no client order ID
- Persisted swap intent has no instrument ID
- Persisted swap intent has no input amount
- 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/be1ffd3bec1243d4.
Report an issue: GitHub.