gleam-lang/gleam · error

invalid segment type in exhaustiveness

Error message

invalid segment type in exhaustiveness {x:?}

What it means

Panic in the exhaustiveness/code-generation pass (compiler-core/src/exhaustiveness.rs:3795) when a bit array segment's type is none of the supported read types: Int, Float, String (utf8), BitArray, or UtfCodepoint. The compiler maps each segment type to a low-level `ReadType`; any other type reaching this code is a compiler-internal invariant violation, so it panics with the offending type in the message.

Solutions

  1. Upgrade to the latest gleam compiler release; earlier validation should reject unsupported segment types before this pass.
  2. Fix the source program so the bit array segment uses a supported type (`int`, `float`, `utf8` string, `bits`/bit array, or `utf_codepoint`).
  3. If you are a compiler developer, add the missing mapping in the `match &segment.type_` or ensure the type checker rejects the segment before exhaustiveness.
  4. File a bug with the `{x:?}` debug output and the offending pattern if it occurs on valid-looking code.

Example fix

// before: unsupported segment type
let <<flag:bool>> = data
// after: use a supported segment type
let <<flag:int>> = data
Defensive patterns

Strategy: validation

Validate before calling

let supported = t.is_int() || t.is_float() || t.is_string() || t.is_bit_array() || t.is_utf_codepoint();
if !supported { return Err(Error::UnsupportedSegmentType); }

Type guard

fn is_supported_read_type(t: &Type) -> bool {
    t.is_int() || t.is_float() || t.is_string() || t.is_bit_array() || t.is_utf_codepoint()
}

Prevention

When it happens

Trigger: A bit array segment pattern whose `type_` is not int/float/string/bit-array/utf-codepoint (e.g. a bool, list, or tuple segment) surviving earlier validation and reaching exhaustiveness code generation — typically via a compiler bug or unvalidated AST from a plugin/patch, not from normal valid Gleam source.

Common situations: Compiler contributors modifying type checking of bit array segments; users on patched/forked compilers compiling programs with unusual segment types; testing `<<x:bool>>`-style segments that validation should have rejected earlier.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14). Data as JSON: /api/errors/d43487a2f9644ffc. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/exhaustiveness.rs:3899

                | ReadSize::VariableBits { .. }
                | ReadSize::BinaryOperator { .. } => {
                    let size = previous_end.clone().add_size(&segment_size);
                    let operator = if is_last_segment {
                        SizeOperator::Equal
                    } else {
                        SizeOperator::GreaterEqual
                    };
                    tests.push_back(BitArrayTest::Size(SizeTest { operator, size }));
                }
            }

            let type_ = match &segment.type_ {
                type_ if type_.is_int() => ReadType::Int,
                type_ if type_.is_float() => ReadType::Float,
                type_ if type_.is_string() => ReadType::String,
                type_ if type_.is_bit_array() => ReadType::BitArray,
                type_ if type_.is_utf_codepoint() => ReadType::UtfCodepoint,
                x => panic!("invalid segment type in exhaustiveness {x:?}"),
            };

            let read_action = ReadAction {
                size: segment_size.clone(),
                from: previous_end.clone(),
                type_,
                endianness: segment.endianness(),
                signed: segment.signed(),
            };

            // Each segment is also turned into a match test, checking the
            // selected bits match with the pattern's value.
            let value = segment_matched_value(segment, None, &read_action);

            // Then if the matched value is a variable that is in scope for the
            // rest of the pattern we keep track of it, so it can be used in the
            // following read actions as a valid size.
            match &value {

View on GitHub (pinned to 49f8762da5)