{"record":{"id":"4383d9d3de0815fd","repo":"nautechsystems/nautilus_trader","slug":"topic-must-be-at-least-32-bytes-was-4383d9","errorCode":null,"errorMessage":"Topic must be at least 32 bytes, was {}","messagePattern":"Topic must be at least 32 bytes, was (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/log.rs","lineNumber":147,"sourceCode":"    decode_hex(hex)\n}\n\n/// Extract address from topic at index.\n///\n/// In Ethereum event logs, indexed address parameters are stored as 32-byte\n/// values with the 20-byte address right-aligned (padded with zeros on the left).\n///\n/// # Errors\n///\n/// Returns an error if the topic is missing or the address extraction fails.\npub fn extract_address_from_topic(\n    log: &RpcLog,\n    index: usize,\n    description: &str,\n) -> anyhow::Result<Address> {\n    let bytes = extract_topic_bytes(log, index)\n        .map_err(|_| anyhow::anyhow!(\"Missing {description} address in topic{index}\"))?;\n    anyhow::ensure!(\n        bytes.len() >= 32,\n        \"Topic must be at least 32 bytes, was {}\",\n        bytes.len()\n    );\n    Ok(Address::from_slice(&bytes[12..32]))\n}\n\n/// Extract data bytes from RPC log.\n///\n/// # Errors\n///\n/// Returns an error if the hex decoding fails.\npub fn extract_data_bytes(log: &RpcLog) -> anyhow::Result<Vec<u8>> {\n    decode_hex(&log.data)\n}\n\n/// Validate event signature from topic0.\n///","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/log.rs#L129-L165","documentation":"This error means the decoded topic bytes were shorter than 32 bytes when extracting an indexed address. Indexed Ethereum parameters occupy a full 32-byte topic, with addresses left-padded to occupy bytes 12..32. A shorter decode implies malformed hex (odd length, truncated string) or a corrupted topic value.","triggerScenarios":"Calling extract_address_from_topic on a topic whose hex decodes to <32 bytes — e.g. a truncated topic string, odd-length hex, or a nonstandard producer emitting shortened topics.","commonSituations":"Corrupted or hand-crafted log fixtures, log data mangled by an intermediate service, or custom chains emitting nonstandard topic widths.","solutions":["Inspect the raw topic hex; it should be 66 characters (0x + 64 hex digits).","Reject or quarantine logs with malformed topics instead of unwrapping.","If your data source legitimately produces shorter encodings, left-pad to 32 bytes before extraction.","Verify no intermediate transformation is trimming/hashing the topics."],"exampleFix":"// before\nlet addr = extract_address_from_topic(&log, 1, \"token0\")?;\n// after\nlet ok = log.topics.get(1).map_or(false, |t| t.trim_start_matches(\"0x\").len() == 64);\nanyhow::ensure!(ok, \"malformed topic: {:?}\", log.topics.get(1));\nlet addr = extract_address_from_topic(&log, 1, \"token0\")?;","handlingStrategy":"validation","validationCode":"fn topic_is_32_bytes(t: &str) -> bool {\n    t.trim_start_matches(\"0x\").len() == 64\n        && t.trim_start_matches(\"0x\").chars().all(|c| c.is_ascii_hexdigit())\n}","typeGuard":"fn full_width_topic(log: &RpcLog, i: usize) -> bool {\n    log.topics.get(i).map_or(false, |t| t.trim_start_matches(\"0x\").len() == 64)\n}","tryCatchPattern":"match extract_address_from_topic(&log, 1, \"token0\") {\n    Ok(a) => a,\n    Err(e) => { quarantine(&log, e); Address::ZERO }\n}","preventionTips":["Topics should be 66 chars (0x + 64 hex digits) — reject shorter strings.","Guard against odd-length hex which fails decoding.","Watch for intermediaries truncating or re-encoding topics.","Left-pad legitimately short encodings before extraction."],"tags":["blockchain","ethereum","topics","validation"],"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-14T00:17:10.932Z"}