{"record":{"id":"f0e4eeb274d86538","repo":"FuelLabs/fuel-core","slug":"could-not-convert-sender-to-address","errorCode":null,"errorMessage":"Could not convert sender to Address: {}","messagePattern":"Could not convert sender to Address: (.+?)","errorType":"exception","errorClass":"Error::Serialization","httpStatus":null,"severity":"error","filePath":"crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs","lineNumber":946,"sourceCode":"            Ok(Input::coin_predicate(\n                utxo_id,\n                owner,\n                proto_coin_predicate.amount,\n                asset_id,\n                tx_pointer,\n                proto_coin_predicate.predicate_gas_used,\n                proto_coin_predicate.predicate.clone(),\n                proto_coin_predicate.predicate_data.clone(),\n            ))\n        }\n        ProtoInputVariant::Contract(proto_contract) => {\n            let contract = contract_input_from_proto(proto_contract)?;\n            Ok(Input::Contract(contract))\n        }\n        ProtoInputVariant::MessageCoinSigned(proto_message) => {\n            let sender =\n                Address::try_from(proto_message.sender.as_slice()).map_err(|e| {\n                    Error::Serialization(anyhow!(\n                        \"Could not convert sender to Address: {}\",\n                        e\n                    ))\n                })?;\n            let recipient = Address::try_from(proto_message.recipient.as_slice())\n                .map_err(|e| {\n                    Error::Serialization(anyhow!(\n                        \"Could not convert recipient to Address: {}\",\n                        e\n                    ))\n                })?;\n            let nonce = fuel_core_types::fuel_types::Nonce::try_from(\n                proto_message.nonce.as_slice(),\n            )\n            .map_err(|e| Error::Serialization(anyhow!(e)))?;\n            let witness_index =\n                u16::try_from(proto_message.witness_index).map_err(|e| {\n                    Error::Serialization(anyhow!(","sourceCodeStart":928,"sourceCodeEnd":964,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs#L928-L964","documentation":"MessageCoinSigned inputs carry a 32-byte sender address; the convertor runs Address::try_from on proto_message.sender and wraps any failure as 'Could not convert sender to Address: {e}'. The try_from fails when the byte slice is not exactly 32 bytes, most commonly 0 (field never set).","triggerScenarios":"A message-coin input with sender unset or wrong width (20-byte address, truncated key). Triggered while decoding any transaction containing message inputs (script/mint with messages).","commonSituations":"Producer omitted sender when relaying messages; bridging tooling emitting L1-style 20-byte addresses; corrupted transport payloads; fixture messages with empty sender.","solutions":["Validate sender.len() == 32 on message inputs before conversion","Fix the message relay/bridge producer to serialize the full Fuel Address of the sender","Where a 20-byte source address is legitimate, hash/pad it to 32 bytes explicitly at the boundary","Include input index and byte length in validation errors to locate the offending producer fast"],"exampleFix":"// before\nlet sender = Address::try_from(proto_message.sender.as_slice()).map_err(...)?;\n\n// after\nif proto_message.sender.len() != 32 {\n    return Err(anyhow!(\"message sender len {} != 32\", proto_message.sender.len()));\n}\nlet sender = Address::try_from(proto_message.sender.as_slice()).map_err(...)?;","handlingStrategy":"validation","validationCode":"fn message_input_is_valid(m: &ProtoMessageCoinSigned) -> bool {\n    m.sender.len() == 32 && m.recipient.len() == 32\n}","typeGuard":"fn is_fuel_address(b: &[u8]) -> bool { b.len() == 32 }","tryCatchPattern":"let sender = Address::try_from(m.sender.as_slice())\n    .with_context(|| format!(\"message sender len {} (expected 32)\", m.sender.len()))?;","preventionTips":["Bridge/relay code must always fill the 32-byte sender when minting message protos","Validate sender and recipient together in one pass","Add message-input fixtures to producer round-trip tests"],"tags":["rust","fuel","protobuf","serialization","message-input","address","validation"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}