{"record":{"id":"f6b555b85fafb4d0","repo":"FuelLabs/fuel-core","slug":"could-not-convert-subsections-number-to-u16","errorCode":null,"errorMessage":"Could not convert subsections_number to u16: {}","messagePattern":"Could not convert subsections_number to u16: (.+?)","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":784,"sourceCode":"                ))\n            })?;\n            let witness_index =\n                u16::try_from(proto_upload.witness_index).map_err(|e| {\n                    Error::Serialization(anyhow!(\n                        \"Could not convert witness_index to u16: {}\",\n                        e\n                    ))\n                })?;\n            let subsection_index =\n                u16::try_from(proto_upload.subsection_index).map_err(|e| {\n                    Error::Serialization(anyhow!(\n                        \"Could not convert subsection_index to u16: {}\",\n                        e\n                    ))\n                })?;\n            let subsections_number = u16::try_from(proto_upload.subsections_number)\n                .map_err(|e| {\n                    Error::Serialization(anyhow!(\n                        \"Could not convert subsections_number to u16: {}\",\n                        e\n                    ))\n                })?;\n            let proof_set = proto_upload\n                .proof_set\n                .iter()\n                .map(|entry| {\n                    Bytes32::try_from(entry.as_slice()).map_err(|e| {\n                        Error::Serialization(anyhow!(\n                            \"Could not convert proof_set entry to Bytes32: {}\",\n                            e\n                        ))\n                    })\n                })\n                .collect::<crate::result::Result<Vec<_>>>()?;\n\n            let body = UploadBody {","sourceCodeStart":766,"sourceCodeEnd":802,"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#L766-L802","documentation":"subsections_number counts how many pieces the uploaded bytecode was split into, stored as u16 in UploadBody. When the proto value does not fit u16 (> 65535 or negative), u16::try_from fails and this error aborts the Upload conversion.","triggerScenarios":"Producer encoded a subsections_number above 65535 — meaning the blob was chunked too finely (chunk size too small) — or garbage data reached the decoder.","commonSituations":"Chunk-size mismatch between uploader and chain rules; a client uploading a huge blob with 1-byte subsections as a bug; corrupted transport payloads.","solutions":["Validate subsections_number <= 65535 (and >= 1) before converting; reject with the actual value in the message","Fix the uploading client to use the chain-mandated subsection size so the count fits u16","Cross-check subsection_index < subsections_number as part of the same pre-validation","Round-trip test upload protos (encode→decode) in CI for both producer and consumer versions"],"exampleFix":"// before\nlet subsections_number = u16::try_from(proto_upload.subsections_number).map_err(...)?;\n\n// after\nlet sn = proto_upload.subsections_number;\nif !(1..=u16::MAX as u32).contains(&sn) {\n    return Err(anyhow!(\"subsections_number {sn} out of u16 range\"));\n}\nlet subsections_number = sn as u16;","handlingStrategy":"validation","validationCode":"fn upload_subsections_number_ok(u: &ProtoUpload) -> bool {\n    (1..=u16::MAX as u32).contains(&u.subsections_number)\n}","typeGuard":"fn valid_subsections_count(n: u32) -> bool { (1..=u16::MAX as u32).contains(&n) }","tryCatchPattern":"let n = u16::try_from(u.subsections_number)\n    .with_context(|| format!(\"subsections_number {} invalid\", u.subsections_number))?;","preventionTips":["Bound blob chunk counts by u16 in the uploader's chunking logic","Reject zero subsection counts as malformed","Keep upload parameter limits in one shared config, not duplicated constants"],"tags":["rust","fuel","protobuf","serialization","upload-transaction","integer-overflow","validation"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}