{"record":{"id":"e0910bdc46978add","repo":"nautechsystems/nautilus_trader","slug":"invalid-hex-characters-in-s","errorCode":null,"errorMessage":"Invalid hex characters in: {s}","messagePattern":"Invalid hex characters in: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_identifier.rs","lineNumber":221,"sourceCode":"    ///\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\"),\n        }\n    }\n}\n\n/// Validates that a string contains only valid hexadecimal characters after \"0x\" prefix.\nfn validate_hex_string(s: &str) -> anyhow::Result<()> {\n    let hex_part = &s[2..];\n    if !hex_part.chars().all(|c| c.is_ascii_hexdigit()) {\n        anyhow::bail!(\"Invalid hex characters in: {s}\");\n    }\n    Ok(())\n}\n\nimpl PartialEq for PoolIdentifier {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (Self::Address(a), Self::Address(b)) | (Self::PoolId(a), Self::PoolId(b)) => {\n                // Case-insensitive comparison\n                a.eq_ignore_ascii_case(b)\n            }\n            // Different variants are never equal\n            _ => false,\n        }\n    }\n}\n\nimpl Eq for PoolIdentifier {}","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_identifier.rs#L203-L239","documentation":"validate_hex_string checks that all characters after the mandatory '0x' prefix are ASCII hex digits. Any non-hex character after '0x' is rejected with this error. It backs new_checked and from_pool_id_hex.","triggerScenarios":"Passing a pool identifier or pool ID containing non-hex characters after '0x' — e.g. whitespace, placeholders like '0x<pool_id>', or labels appended to the ID.","commonSituations":"Copy-paste errors from docs or explorers including spaces or annotations; template placeholders not substituted; encoding bugs producing non-ASCII lookalike characters.","solutions":["Inspect the string for non [0-9a-fA-F] characters after '0x'","Strip whitespace and trailing punctuation before constructing","Validate with a regex/scan before calling new_checked or from_pool_id_hex"],"exampleFix":"// before\nlet pid = PoolIdentifier::new_checked(\"0x 9243eb4d\")?;\n// after\nlet cleaned = value.trim();\nassert!(cleaned[2..].chars().all(|c| c.is_ascii_hexdigit()));\nlet pid = PoolIdentifier::new_checked(cleaned)?;","handlingStrategy":"validation","validationCode":"fn is_valid_hex_id(s: &str) -> bool {\n    s.len() >= 2 && s.starts_with(\"0x\") && s[2..].chars().all(|c| c.is_ascii_hexdigit())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Trim whitespace before constructing identifiers","Sanitize copy-pasted values (no spaces, labels, or annotations)","Validate with a regex ^0x[0-9a-fA-F]+$ before calling"],"tags":["rust","validation","hex","defi"],"backgroundTag":"invalid-argument-format","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"}