gleam-lang/gleam · error · ErrorType

ErrorType::UnitMustHaveSize

Error message

ErrorType::UnitMustHaveSize

What it means

A segment carrying the `unit` option must also carry an explicit `size` option, since `unit(N)` is only a multiplier of an explicit size. `type_options` checks for `unit: Some(_)` with `size: None` and raises `UnitMustHaveSize` at the `unit` option's location.

Solutions

  1. Add a `size` option alongside `unit`, e.g. `<<x:unit(8)-size(2)>>` for a 16-bit segment.
  2. Replace `unit(N)` with `size(N)` if a fixed size alone was intended.
  3. Remove the `unit` option entirely to use the value's natural size.

Example fix

// before
let a = <<x:unit(8)>>
// after
let a = <<x:unit(8)-size(2)>>
Defensive patterns

Strategy: validation

Validate before calling

// unit(N) requires an explicit size in the same segment.
fn unit_without_size(has_unit: Bool, has_size: Bool) -> Bool {
  has_unit && !has_size
}

Prevention

When it happens

Trigger: Writing `<<x:unit(8)>>` or `<<x:int-unit(8)>>` with no `size(...)` in the same segment, in a bit array expression or a pattern.

Common situations: Mistaking `unit` for a standalone size; translating Erlang specs where unit appeared with an implicit size; dropping a `size(...)` option during refactoring.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at compiler-core/src/bit_array.rs:309

            return err(
                ErrorType::TypeDoesNotAllowSize {
                    type_: type_.label(),
                },
                size.location(),
            );
        }

        _ => {}
    }

    // if unit specified, size must be specified
    if let SegmentOptionCategories {
        unit: Some(unit),
        size: None,
        ..
    } = categories
    {
        return err(ErrorType::UnitMustHaveSize, unit.location());
    }

    // float only 16/32/64
    if let SegmentOptionCategories {
        type_: Some(Float { .. }),
        size: Some(size),
        ..
    } = categories
        && let Some(abox) = size.value()
    {
        match abox.as_int_literal() {
            None => (),
            Some(value) if value == 16.into() || value == 32.into() || value == 64.into() => (),
            _ => return err(ErrorType::FloatWithSize, size.location()),
        }
    }

    // Segment patterns with a zero or negative constant size must be rejected,

View on GitHub (pinned to 15b07c7830)