{"record":{"id":"087d60498e2d69b3","repo":"gleam-lang/gleam","slug":"bytes-must-not-be-empty","errorCode":null,"errorMessage":"bytes must not be empty","messagePattern":"bytes must not be empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/exhaustiveness.rs","lineNumber":4061,"sourceCode":"        }\n        // If the number needs fewer bits than the read size, we pad it.\n        // <3:9> yields the bytes [0b0000_0011]. We add one digit and get 0_0000_0011\n        (Endianness::Big, Ordering::Less) => {\n            let mut bits = BitVec::repeat(pad_digit, size - bytes_size);\n            bits.extend_from_raw_slice(&bytes);\n            bits\n        }\n\n        (Endianness::Little, Ordering::Greater) => {\n            // If the difference is greater than a byte, we returned an Error earlier\n            let remainder = size % 8;\n            if remainder == 0 {\n                BitVec::from_vec(bytes)\n            } else {\n                // If the size is not a multiple of 8, we need to truncate the most significant bits.\n                // As they are in the last byte, we leftshift by the appropriate amount and\n                // truncate the final bits after conversion\n                let last_byte = bytes.last_mut().expect(\"bytes must not be empty\");\n                *last_byte <<= 8 - remainder;\n\n                let mut bits = BitVec::from_vec(bytes);\n                bits.truncate(size);\n                bits\n            }\n        }\n        (Endianness::Little, Ordering::Less) => {\n            let mut bits = BitVec::from_vec(bytes);\n            let padding: BitVec<u8, Msb0> = BitVec::repeat(pad_digit, size - bytes_size);\n            bits.extend_from_bitslice(padding.as_bitslice());\n            bits\n        }\n    };\n    Ok(bits)\n}\n\nfn int_to_bytes(value: &BigInt, endianness: Endianness, signed: bool) -> Vec<u8> {","sourceCodeStart":4043,"sourceCodeEnd":4079,"githubUrl":"https://github.com/gleam-lang/gleam/blob/49f8762da595eb3c8f576656a4200a142ca188c9/compiler-core/src/exhaustiveness.rs#L4043-L4079","documentation":"Inside the bit-width conversion for bit-array pattern/value matching, the code left-shifts the last byte of a byte vector to drop excess bits when the bit size isn't a multiple of 8. `bytes.last_mut().expect(\"bytes must not be empty\")` panics if the byte vector is empty, i.e. a zero-byte BitVec was passed in. The invariant is that a bit array with a non-zero size in bits has at least one byte.","triggerScenarios":"Calling the bit-array size/truncation helper with `bytes` empty while `remainder != 0` — e.g. size in bits > 0 but the byte conversion produced no bytes, or a zero-sized bit array segment whose remainder computation is inconsistent.","commonSituations":"Hit during Gleam compiler work on bit-array pattern matching: passing an empty `Vec<u8>` from an integer-to-bytes conversion for a zero value with a small segment size, or a bug in segment size validation.","solutions":["Ensure the bytes conversion produces at least one byte for any non-zero bit size before calling this code","Short-circuit: if `bytes.is_empty()`, return `BitVec::new()` (or `BitVec::from_vec(bytes)`) instead of shifting","Validate that segment `size > 0` and that `size`/8 == bytes.len() (or len+1) upstream","If reproducible with valid Gleam source, file a compiler bug with the bit-array expression"],"exampleFix":"// before\nlet last_byte = bytes.last_mut().expect(\"bytes must not be empty\");\n*last_byte <<= 8 - remainder;\n// after\nif bytes.is_empty() {\n    return BitVec::new();\n}\n*bytes.last_mut().unwrap() <<= 8 - remainder;","handlingStrategy":"validation","validationCode":"if size == 0 || bytes.is_empty() {\n    return BitVec::new();\n}","typeGuard":"fn convertible(bytes: &[u8], size: usize) -> bool { !bytes.is_empty() && size > 0 && size <= bytes.len() * 8 }","tryCatchPattern":null,"preventionTips":["Always produce at least one byte from integer-to-bytes conversion for non-zero sizes","Check segment size invariants before bit-level truncation","Test bit-array patterns with size 0, 1..8, and multiples of 8"],"tags":["rust","bit-array","panic","pattern-matching"],"backgroundTag":"internal-invariant-violation","analyzedSha":"49f8762da595eb3c8f576656a4200a142ca188c9","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}