{"record":{"id":"7f6396aa1ad68f69","repo":"linera-io/linera-protocol","slug":"invalid-topic-e","errorCode":null,"errorMessage":"invalid topic: {e}","messagePattern":"invalid topic: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-bridge/src/proof/mod.rs","lineNumber":580,"sourceCode":"    let address = <Address as alloy_rlp::Decodable>::decode(&mut log_data_buf)\n        .map_err(|e| anyhow!(\"invalid log address: {e}\"))?;\n\n    // Decode topics list\n    let topics_header = alloy_rlp::Header::decode(&mut log_data_buf)\n        .map_err(|e| anyhow!(\"invalid topics list RLP: {e}\"))?;\n    ensure!(topics_header.list, \"topics must be an RLP list\");\n    ensure!(\n        log_data_buf.len() >= topics_header.payload_length,\n        \"topics payload extends past log boundary\"\n    );\n\n    let mut topics_data = &log_data_buf[..topics_header.payload_length];\n    log_data_buf = &log_data_buf[topics_header.payload_length..];\n\n    let mut topics = Vec::new();\n    while !topics_data.is_empty() {\n        let topic = <B256 as alloy_rlp::Decodable>::decode(&mut topics_data)\n            .map_err(|e| anyhow!(\"invalid topic: {e}\"))?;\n        topics.push(topic);\n    }\n\n    // Decode log data (byte string)\n    let data_header = alloy_rlp::Header::decode(&mut log_data_buf)\n        .map_err(|e| anyhow!(\"invalid log data RLP: {e}\"))?;\n    ensure!(\n        !data_header.list,\n        \"log data must be a byte string, not a list\"\n    );\n    ensure!(\n        log_data_buf.len() >= data_header.payload_length,\n        \"log data extends past log boundary\"\n    );\n    let log_bytes = log_data_buf[..data_header.payload_length].to_vec();\n    log_data_buf = &log_data_buf[data_header.payload_length..];\n\n    ensure!(","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-bridge/src/proof/mod.rs#L562-L598","documentation":"One of the entries inside the topics list did not decode as a B256 (32-byte) value. Every Ethereum topic must be an RLP string of exactly 32 bytes; anything else — wrong length, a list, or a truncated tail — fails here.","triggerScenarios":"decode_log iterating topics_data: a topic shorter/longer than 32 bytes, a nested list where a string was expected, or a topics payload whose boundary leaves a partial topic at the end.","commonSituations":"Producers that encode topics with variable-length integers instead of fixed 32-byte words; a topic count/payload length mismatch in hand-built fixtures; bytes shifted by one after an off-by-one in the topics header.","solutions":["Pre-validate with alloy_primitives::Log::decode, which enforces 32-byte topics exactly.","Inspect the failing topic's RLP prefix: 0xa0 means a 32-byte string — anything else indicates a malformed topic.","Fix the event-encoding side so indexed parameters are abi.encode()-padded to 32 bytes.","Rebuild the receipt proof from the chain."],"exampleFix":"// before: every remaining byte-range is treated as a topic\nlet topic = <B256 as alloy_rlp::Decodable>::decode(&mut topics_data)\n    .map_err(|e| anyhow!(\"invalid topic: {e}\"))?;\n\n// after: only accept logs whose topics are canonical 32-byte words\nuse alloy_rlp::Decodable;\nanyhow::ensure!(\n    alloy_primitives::Log::decode(&mut &log_entry_bytes[..]).is_ok(),\n    \"non-32-byte topic in log — rejecting entry\"\n);","handlingStrategy":"validation","validationCode":"use alloy_rlp::Decodable;\nfn topics_are_canonical(rlp: &[u8]) -> bool {\n    alloy_primitives::Log::decode(&mut &rlp[..]).is_ok() // every topic must be 32 bytes\n}","typeGuard":null,"tryCatchPattern":"Err(e) if e.to_string().contains(\"invalid topic\") => reject_proof(e), // permanent data error","preventionTips":["Pad all indexed event parameters to 32 bytes (standard ABI encoding) in any custom prover.","Treat any decode family error as proof rejection in bridge verification logic."],"tags":["rlp","ethereum","topics","b256","decoding"],"backgroundTag":"rlp-decoding-failed","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}