{"record":{"id":"758faaf34a44fe3b","repo":"nautechsystems/nautilus_trader","slug":"pool-identifier-pool-identifier-is-a-pool-id-on","errorCode":null,"errorMessage":"Pool identifier {pool_identifier} is a pool ID; only address identifiers are supported","messagePattern":"Pool identifier (.+?) is a pool ID; only address identifiers are supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":819,"sourceCode":"            })\n    }\n\n    fn resolve_pool(&self, instrument_id: &InstrumentId) -> anyhow::Result<Pool> {\n        let (blockchain, dex_type) = instrument_id.venue.parse_dex()?;\n        if blockchain != self.chain.name {\n            anyhow::bail!(\n                \"Pool venue chain {blockchain} does not match the client chain {}\",\n                self.chain.name\n            );\n        }\n\n        if dex_type != DexType::UniswapV3 {\n            anyhow::bail!(\"Unsupported DEX type {dex_type}; only UniswapV3 is supported\");\n        }\n\n        let pool_identifier = PoolIdentifier::new_checked(instrument_id.symbol.as_str())?;\n        if !pool_identifier.is_address() {\n            anyhow::bail!(\n                \"Pool identifier {pool_identifier} is a pool ID; only address identifiers are supported\"\n            );\n        }\n\n        let pool = self\n            .core\n            .cache()\n            .pool(instrument_id)\n            .cloned()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Unknown pool {instrument_id}; not found in the shared engine cache\"\n                )\n            })?;\n\n        if pool.token0.get_token_priority() == pool.token1.get_token_priority() {\n            anyhow::bail!(\n                \"Pool {instrument_id} tokens share a token priority; base and quote orientation is ambiguous\"","sourceCodeStart":801,"sourceCodeEnd":837,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L801-L837","documentation":"resolve_pool() requires the instrument ID's symbol to be a pool contract address (checked via `PoolIdentifier::is_address()`), not a symbolic pool ID. This adapter identifies on-chain pools directly by their deployed contract address so it can bind to the exact Uniswap V3 pool, rather than resolving human-readable pool IDs. A non-address symbol bails before the cache lookup.","triggerScenarios":"Calling `preflight`, `restore_swap_plan`, or `prepare_swap` with an `InstrumentId` whose symbol is a pool ID string (e.g. `ETH-USDC` or a Nautilus-generated pool identifier) instead of a 0x-prefixed 20-byte hex address. The venue must be correct (chain and UniswapV3 pass earlier checks) for this error to be reached.","commonSituations":"Constructing instrument IDs from data catalogs or strategy configs that use symbolic identifiers (e.g. `ethereum/uniswap_v3:ETH-USDC`); copying instruments from docs/examples that use symbolic names; a fixture or registry that produced pool-ID style symbols; forgetting to map a human-readable pair name to its V3 pool address at config time.","solutions":["Replace the symbol with the pool's contract address, e.g. `ethereum/uniswap_v3:0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640`.","If you only know the pair, derive the pool address from the Uniswap V3 factory (`getPool(tokenA, tokenB, fee)`) or a deployment registry at configuration time and use that address.","Add a startup validation step that asserts every swap instrument's symbol is a hex address, failing fast before any swap is attempted."],"exampleFix":"// before\nlet id = InstrumentId::from(\"ethereum/uniswap_v3:ETH-USDC\");\nclient.preflight(&id, ...).await?;\n\n// after\nlet id = InstrumentId::from(\"ethereum/uniswap_v3:0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\");\nclient.preflight(&id, ...).await?;","handlingStrategy":"validation","validationCode":"let symbol = instrument_id.symbol.as_str();\nlet is_addr = symbol.starts_with(\"0x\")\n    && symbol.len() == 42\n    && Address::parse_checksummed(symbol, None).is_ok();\nif !is_addr {\n    anyhow::bail!(\"symbol '{symbol}' is not a pool address; resolve the V3 pool address first\");\n}\n// safe to call client.prepare_swap(...).await?","typeGuard":"fn symbol_is_pool_address(instrument_id: &InstrumentId) -> bool {\n    let s = instrument_id.symbol.as_str();\n    s.starts_with(\"0x\") && s.len() == 42 && Address::parse_checksummed(s, None).is_ok()\n}","tryCatchPattern":"match client.preflight(&instrument_id, quote, slippage).await {\n    Err(e) if e.to_string().contains(\"only address identifiers are supported\") => {\n        error!(\"use a 0x pool address symbol, not a symbolic pool ID: {}\", instrument_id);\n    }\n    other => other?,\n}","preventionTips":["Resolve pair names to Uniswap V3 pool addresses (factory getPool) at config load time and store only address-based instrument IDs.","Add a startup check that every swap instrument symbol parses as a checksummed hex address.","Avoid copying symbolic IDs (ETH-USDC style) from catalogs or examples into venue strings for this adapter."],"tags":["blockchain","instrument-id","uniswap-v3","identifier-format","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}