{"record":{"id":"6e28e1150e1ec337","repo":"nautechsystems/nautilus_trader","slug":"pool-id-must-be-32-bytes-was","errorCode":null,"errorMessage":"Pool ID must be 32 bytes, was {}","messagePattern":"Pool ID must be 32 bytes, was (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_identifier.rs","lineNumber":123,"sourceCode":"    pub fn new<T: AsRef<str>>(value: T) -> Self {\n        Self::new_checked(value).expect(FAILED)\n    }\n\n    /// Creates an Address variant from an alloy Address.\n    ///\n    /// Returns the checksummed representation.\n    #[must_use]\n    pub fn from_address(address: Address) -> Self {\n        Self::Address(Ustr::from(address.to_checksum(None).as_str()))\n    }\n\n    /// Creates a `PoolId` variant from raw bytes (32 bytes).\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if bytes length is not 32.\n    pub fn from_pool_id_bytes(bytes: &[u8]) -> anyhow::Result<Self> {\n        anyhow::ensure!(\n            bytes.len() == 32,\n            \"Pool ID must be 32 bytes, was {}\",\n            bytes.len()\n        );\n\n        Ok(Self::PoolId(Ustr::from(&hex::encode_prefixed(bytes))))\n    }\n\n    /// Creates a `PoolId` variant from a hex string (with or without 0x prefix).\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the string is not valid 64-character hex.\n    pub fn from_pool_id_hex<T: AsRef<str>>(hex: T) -> anyhow::Result<Self> {\n        let hex = hex.as_ref();\n        let hex_str = hex.strip_prefix(\"0x\").unwrap_or(hex);\n\n        anyhow::ensure!(","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_identifier.rs#L105-L141","documentation":"`PoolIdentifier::from_pool_id_bytes` builds a DeFi pool identifier from raw 32-byte pool ID data. The library throws this error when the input slice is not exactly 32 bytes, because a pool ID is defined as a 256-bit value (encoded as 0x-prefixed 64-char hex). Any other length cannot represent a valid pool ID.","triggerScenarios":"Calling `from_pool_id_bytes` with a slice whose len != 32 — e.g. passing 20-byte Ethereum addresses, truncated hex output, or byte arrays decoded from shorter/longer hex strings.","commonSituations":"Developers confuse 20-byte EVM addresses with 32-byte pool IDs, slice a larger buffer (calldata, log topics) with wrong offsets, or decode hex without checking decoded length.","solutions":["Verify the source data is exactly 32 bytes before calling (e.g. `assert_eq!(bytes.len(), 32)` or decode with `hex::decode_array::<32>`).","If you have a 20-byte address, use the `Address`-based constructor instead of `from_pool_id_bytes`.","Check slicing offsets/indices on the parent buffer to ensure a full 32-byte word is captured.","Log the actual `bytes.len()` at the call site to diagnose truncation."],"exampleFix":"// before\nlet id = PoolIdentifier::from_pool_id_bytes(&topic_bytes[12..])?; // 20 bytes\n// after\nlet id = PoolIdentifier::from_pool_id_bytes(&topic_bytes)?; // full 32-byte topic","handlingStrategy":"validation","validationCode":"fn ensure_32_bytes(bytes: &[u8]) -> Result<(), String> {\n    if bytes.len() == 32 { Ok(()) } else { Err(format!(\"expected 32 bytes, got {}\", bytes.len())) }\n}","typeGuard":"fn is_pool_id_bytes(bytes: &[u8]) -> bool { bytes.len() == 32 }","tryCatchPattern":"match PoolIdentifier::from_pool_id_bytes(&bytes) {\n    Ok(id) => id,\n    Err(e) => { log::warn!(\"bad pool id bytes: {e}\"); PoolIdentifier::default() }\n}","preventionTips":["Never pass 20-byte addresses where 32-byte pool IDs are expected","Decode hex with fixed-size helpers (hex::decode_array::<32>) so length is enforced by types","Check slice offsets when extracting words from calldata or log topics"],"tags":["defi","validation","byte-length","argument"],"backgroundTag":"invalid-argument-value","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"}