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

  1. 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).
  2. Verify the pool address in the instrument_id is correct — a wrong pool may legitimately contain two equal-priority tokens.
  3. Re-sync/rebuild the pool entry in the shared engine cache so token0/token1 metadata carries the correct priorities.
  4. 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

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


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