{"record":{"id":"ab1ecdc73fbc7750","repo":"FuelLabs/fuel-core","slug":"could-not-convert-recipient-to-address","errorCode":null,"errorMessage":"Could not convert recipient to Address: {}","messagePattern":"Could not convert recipient 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":953,"sourceCode":"                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!(\n                        \"Could not convert witness_index to u16: {}\",\n                        e\n                    ))\n                })?;\n\n            Ok(Input::message_coin_signed(\n                sender,","sourceCodeStart":935,"sourceCodeEnd":971,"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#L935-L971","documentation":"The companion check to error 197: MessageCoinSigned recipient bytes must convert to a 32-byte Address. Address::try_from on proto_message.recipient fails for any length other than 32 and is reported as 'Could not convert recipient to Address: {e}'.","triggerScenarios":"A message-coin input whose recipient is unset (0 bytes) or a non-32-byte value; sender may have passed just before this check fails.","commonSituations":"Bridge/relay producers that drop recipient on failure paths; address-format mismatches from other ecosystems; truncated payloads; incomplete test messages.","solutions":["Validate both sender and recipient are 32 bytes before converting message inputs","Fix the producer to always set the recipient Address on message coins","Reject unspendable messages (empty recipient) at ingestion with a targeted message instead of a generic conversion error","Add round-trip serialization tests for message inputs in the producer"],"exampleFix":"// before\nlet recipient = Address::try_from(proto_message.recipient.as_slice()).map_err(...)?;\n\n// after\nfor (name, b) in [(\"sender\", &proto_message.sender), (\"recipient\", &proto_message.recipient)] {\n    if b.len() != 32 { return Err(anyhow!(\"message {name} len {} != 32\", b.len())); }\n}\nlet recipient = Address::try_from(proto_message.recipient.as_slice()).map_err(...)?;","handlingStrategy":"validation","validationCode":"fn message_input_is_valid(m: &ProtoMessageCoinSigned) -> bool {\n    m.sender.len() == 32 && m.recipient.len() == 32 && m.nonce.len() == 32\n}","typeGuard":"fn is_fuel_address(b: &[u8]) -> bool { b.len() == 32 }","tryCatchPattern":"let recipient = Address::try_from(m.recipient.as_slice())\n    .with_context(|| format!(\"message recipient len {} (expected 32)\", m.recipient.len()))?;","preventionTips":["Reject messages with empty recipients at ingestion — they are unspendable","Validate all fixed-width fields (sender, recipient, nonce) in a single pre-pass","Round-trip test message inputs end to end"],"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"}