nautechsystems/nautilus_trader · error
Pool {instrument_id} tokens share a token priority; base and
Error message
Pool {instrument_id} tokens share a token priority; base and quote orientation is ambiguous What it means
resolve_pool() loads a Uniswap V3 pool from the shared engine cache and validates that its two tokens can be oriented as base and quote. This error is thrown when both tokens report the same get_token_priority(), so the client cannot unambiguously decide which token is base and which is quote for order-side (buy/sell) semantics. It is a deliberate fail-fast to prevent swaps being built with inverted base/quote direction.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:836
if !pool_identifier.is_address() {
anyhow::bail!(
"Pool identifier {pool_identifier} is a pool ID; only address identifiers are supported"
);
}
let pool = self
.core
.cache()
.pool(instrument_id)
.cloned()
.ok_or_else(|| {
anyhow::anyhow!(
"Unknown pool {instrument_id}; not found in the shared engine cache"
)
})?;
if pool.token0.get_token_priority() == pool.token1.get_token_priority() {
anyhow::bail!(
"Pool {instrument_id} tokens share a token priority; base and quote orientation is ambiguous"
);
}
Ok(pool)
}
/// Authenticates every persisted signed transaction in this execution database.
///
/// Run this while the execution client is disconnected. The check takes a stable table lock,
/// reads in bounded batches, and returns counts, deployment identity, key IDs, and database
/// roles with direct ownership or `SELECT` grants.
///
/// # Errors
///
/// Returns an error for inconsistent storage state, missing keys, or any payload which cannot
/// be opened and authenticated against its durable intent.
pub async fn check_payload_storage(View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the token priority configuration so the pool's two tokens have distinct priorities (e.g. rank the intended quote token lower/higher than the base token).
- Verify the pool address in the instrument_id is correct — a wrong pool may legitimately contain two equal-priority tokens.
- Re-sync/rebuild the pool entry in the shared engine cache so token0/token1 metadata carries the correct priorities.
- If the pair genuinely has no meaningful priority ordering (e.g. two equal stablecoins), use a different pool or explicit base/quote instrument definition that this client supports.
Example fix
// before: both tokens share default priority 0
// token_registry: { USDC: 0, DAI: 0 }
// after: assign distinct priorities so orientation is unambiguous
// token_registry: { USDC: 1, DAI: 0 } Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate pool token priorities before requesting a swap
fn pool_orientation_ok(pool: &Pool) -> bool {
pool.token0.get_token_priority() != pool.token1.get_token_priority()
}
// call before prepare_swap; skip/reject instruments where it returns false Type guard
fn has_distinct_priorities(pool: &Pool) -> bool {
pool.token0.get_token_priority() != pool.token1.get_token_priority()
} Prevention
- Assign unique, documented token priorities in your token registry and validate no two tokens in a supported pool share one.
- Add a startup check over cached pools that flags equal-priority pairs before trading begins.
- Prefer address-based pool identifiers from a trusted source so the correct pool is loaded.
When it happens
Trigger: Calling resolve_pool — directly via preflight, or indirectly via prepare_swap or restore_swap_plan — with an instrument_id for a pool whose token0 and token1 have identical token priority values (e.g. a same-priority token pair like two stablecoins with equal configured priority, or a pool created from a misconfigured token registry).
Common situations: A token priority table/registry that assigns the same priority to two tokens in a pool; a pool instrument added to the cache whose tokens were not ranked (both default priority); wrapping two identical or mirrored tokens into one pool; stale cache entries after a token registry update changed priorities to collide.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Chain ID mismatch at connect: expected {expected_chain_id},
- Finalized transaction {} emitted {} Swap logs; expected exac
- Unsupported blockchain {blockchain} for RPC connection
- Missing tickLower in topic2 when parsing burn event
- Missing tickUpper in topic3 when parsing burn event
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d684b8e990fb74ad.
Report an issue: GitHub.