Bit array pattern match using a bits-size that uses the same variable name for the size and the segment generates incorrect code for JavaScript
Author: TigerWaltsCreated Aug 25, 2026Updated Sep 10, 2026
Labelshelp wanted
Gleam: 1.18.1 Environment: Any Target: JavaScript (Erlang not affected)
Using the same name for the captured segment and the bits-size() parameter will result in the generated JavaScript using the wrong variable in the bitArraySlice() function.
pub fn main() {
let prefix = 8
let data = << 35, 36 >>
case data {
<<
prefix:bits-size(prefix),
rest:bits
>> -> #(prefix, rest)
_ -> #(data, <<>>)
} |> echo
Nil
}export function main() {
let prefix = 8;
let data = toBitArray([35, 36]);
let _block;
if (prefix >= 0 && data.bitSize >= prefix) {
let prefix$1 = bitArraySlice(data, 0, prefix$1); // Argument should be prefix
let rest = bitArraySlice(data, prefix$1); // Argument should be prefix
_block = [prefix$1, rest];
} else {
_block = [data, toBitArray([])];
}
let _pipe = _block;
echo(_pipe, undefined, "src/main.gleam", 10);
return undefined;
}This results in the runtime error:
ReferenceError: Cannot access 'prefix$1' before initialization
Using different names doesn't have this problem:
pub fn main() {
let prefix_size = 8
let data = << 35, 36 >>
case data {
<<
prefix:bits-size(prefix_size),
rest:bits
>> -> #(prefix, rest)
_ -> #(data, <<>>)
} |> echo
Nil
}export function main() {
let prefix_size = 8;
let data = toBitArray([35, 36]);
let _block;
if (prefix_size >= 0 && data.bitSize >= prefix_size) {
let prefix = bitArraySlice(data, 0, prefix_size);
let rest = bitArraySlice(data, prefix_size);
_block = [prefix, rest];
} else {
_block = [data, toBitArray([])];
}
let _pipe = _block;
echo(_pipe, undefined, "src/main.gleam", 10);
return undefined;
}Source: gleam-lang/gleam