gleam-lang/gleam · error

variable with no constructor

Error message

variable with no constructor

What it means

This is an internal compiler invariant panic in Erlang code generation for bit array patterns. After type checking, every variable used as a bit array segment size must either be a known aliased literal or have a resolved `ValueConstructor` (local variable, module constant, etc.). When a variable reaches `Pattern` codegen with `constructor: None`, the compiler has no way to emit code for it and panics with `expect("variable with no constructor")`.

Solutions

  1. Reduce the failing bit array pattern to a minimal example and file a bug against the Gleam compiler (this is an internal invariant violation)
  2. Upgrade to the latest Gleam version — such codegen invariants are frequently fixed in patch releases
  3. Work around by binding the size to a plain local variable before the pattern, or inlining a literal size instead of a constant/alias reference

Example fix

// before (Gleam, suspected buggy shape)
let n = 16
assert <<x:size(n)>> = data
// after (workaround: literal or pre-bound plain variable)
assert <<x:size(16)>> = data
Defensive patterns

Strategy: fallback

Validate before calling

// Gleam-side pre-check: ensure bit-array size references a plain literal or simple local
// e.g. prefer `<<x:size(16)>>` over `<<x:size(n)>>` where n comes from a constant/alias

Try / catch

// compiler panics cannot be caught; wrap the compiler invocation in the shell:
gleam build || echo "compiler panicked (ICE) — reduce snippet and file a bug"

Prevention

When it happens

Trigger: Compiling a Gleam bit array pattern whose segment size references a variable that lacks a constructor entry — typically the result of a type-checker/codegen mismatch, e.g. a size expression naming a variable introduced by an alias or import that was not registered during analysis, or a compiler bug where an aliased-literal entry has a non-int variant (`Some(_) => panic!("segment size that is not int made it through type checking")` is the sibling check).

Common situations: Users hitting this have usually written an unusual bit array pattern (e.g. `<<x:size(n)>>` where `n` comes from a constant or alias) on a Gleam version with a codegen bug. It surfaces as a compiler panic (ICE) rather than a user-facing diagnostic.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14). Data as JSON: /api/errors/0295479689b88f3d. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/erlang/pattern.rs:316

        size: &'a TypedBitArraySize,
    ) {
        match size {
            BitArraySize::Int {
                int_value,
                location,
                ..
            } => builder.int_expression(*location, int_value.clone()),
            BitArraySize::Block { inner, .. } => self.bit_array_size(builder, inner),

            BitArraySize::Variable {
                constructor, name, ..
            } => match self.variables_to_add_later.get(name) {
                Some(AliasedLiteral::Int { value, location }) => {
                    builder.int_expression(*location, value.clone())
                }
                Some(_) => panic!("segment size that is not int made it through type checking"),
                None => {
                    let constructor = constructor.as_ref().expect("variable with no constructor");
                    match &constructor.variant {
                        ValueConstructorVariant::ModuleConstant { literal, .. } => {
                            self.generator.inlined_constant(builder, literal);
                        }
                        ValueConstructorVariant::LocalVariable { location, .. } => {
                            builder.variable(*location, &self.generator.local_var_name(location));
                        }
                        ValueConstructorVariant::ModuleFn { .. }
                        | ValueConstructorVariant::Record { .. } => panic!("invalid segment"),
                    }
                }
            },

            BitArraySize::BinaryOperator {
                operator,
                left,
                right,
                location,

View on GitHub (pinned to 15b07c7830)