{"record":{"id":"5f3b8e6086d7ba54","repo":"nautechsystems/nautilus_trader","slug":"cannot-convert-poolid-variant-to-address","errorCode":null,"errorMessage":"Cannot convert PoolId variant to Address","messagePattern":"Cannot convert PoolId variant to Address","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_identifier.rs","lineNumber":194,"sourceCode":"\n    /// Returns true if this is a `PoolId` variant (V4 pools).\n    #[must_use]\n    pub fn is_pool_id(&self) -> bool {\n        matches!(self, Self::PoolId(_))\n    }\n\n    /// Converts to native Address type (V2/V3 pools only).\n    ///\n    /// Returns the underlying Address for use with alloy/ethers operations.\n    ///\n    /// # Errors\n    ///\n    /// Returns error if this is a `PoolId` variant or if parsing fails.\n    pub fn to_address(&self) -> anyhow::Result<Address> {\n        match self {\n            Self::Address(s) => Address::parse_checksummed(s.as_str(), None)\n                .map_err(|e| anyhow::anyhow!(\"Failed to parse address: {e}\")),\n            Self::PoolId(_) => anyhow::bail!(\"Cannot convert PoolId variant to Address\"),\n        }\n    }\n\n    /// Converts to native bytes array (V4 pools only).\n    ///\n    /// Returns the 32-byte pool ID for use in V4-specific operations.\n    ///\n    /// # Errors\n    ///\n    /// Returns error if this is an Address variant or if hex decoding fails.\n    pub fn to_pool_id_bytes(&self) -> anyhow::Result<[u8; 32]> {\n        match self {\n            Self::PoolId(s) => {\n                let hex_str = s.strip_prefix(\"0x\").unwrap_or(s.as_str());\n                hex::decode_array::<32>(hex_str)\n                    .map_err(|e| anyhow::anyhow!(\"Failed to decode pool ID hex: {e}\"))\n            }\n            Self::Address(_) => anyhow::bail!(\"Cannot convert Address variant to PoolId bytes\"),","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_identifier.rs#L176-L212","documentation":"PoolIdentifier is an enum of Address (20-byte) and PoolId (32-byte V4) variants; to_address only makes sense for the Address variant. Calling it on a PoolId variant bails with this error because a 32-byte pool ID cannot be represented as a 20-byte Address.","triggerScenarios":"Calling pool_identifier.to_address() on a value constructed via new_checked with a 66-char pool ID or from_pool_id_hex.","commonSituations":"Generic code that assumes all pool identifiers are addresses; subscribing to Uniswap V4 pools (which use pool IDs) and then calling address-only APIs.","solutions":["Match on the PoolIdentifier enum and handle the PoolId variant separately before calling to_address","Use to_pool_id_bytes for V4 pool identifiers instead","Check the variant with matches! or an is-style helper before conversion"],"exampleFix":"// before\nlet addr = pool_id.to_address()?;\n// after\nlet addr = match &pool_id {\n    PoolIdentifier::Address(_) => pool_id.to_address()?,\n    PoolIdentifier::PoolId(_) => anyhow::bail!(\"V4 pool: use to_pool_id_bytes()\"),\n};","handlingStrategy":"type-guard","validationCode":"matches!(pid, PoolIdentifier::Address(_))","typeGuard":"fn is_address_variant(pid: &PoolIdentifier) -> bool {\n    matches!(pid, PoolIdentifier::Address(_))\n}","tryCatchPattern":"match pid.to_address() {\n    Ok(a) => use_address(a),\n    Err(e) if e.to_string().contains(\"PoolId variant\") => handle_v4_pool(pid),\n    Err(e) => return Err(e),\n}","preventionTips":["Track whether a pool is V4 (PoolId) or V2/V3 (Address) in your own types","Branch on the enum variant before any conversion"],"tags":["rust","defi","enum","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}