gleam-lang/gleam · error

Custom type constructor exist for type

Error message

Custom type constructor exist for type

What it means

In the same constructor-to-term conversion, `variants.get(*index).expect("Custom type constructor exist for type")` panics when the recorded constructor index is out of bounds for the type's variant list. The invariant is that any constructor check's index refers to an existing variant of its type.

Solutions

  1. Ensure the same environment population order is used when building checks and when converting them back to terms
  2. Validate `index < variants.len()` when creating constructor checks to fail earlier with context
  3. If variants are filtered, remap indices instead of leaving gaps
  4. End users: file a compiler bug with the multi-constructor type and match that triggers it

Example fix

// before
.expect("Custom type constructor exist for type")
// after
.unwrap_or_else(|| panic!("constructor index {} out of range for type {}::{} (has {} variants)", index, module, name, variants.len()))
Defensive patterns

Strategy: validation

Validate before calling

if *index >= variants.len() {
    return Err(Error::ConstructorIndexOutOfRange { index, variants: variants.len() });
}

Type guard

fn valid_variant_index(index: usize, variants: &[Variant]) -> bool { index < variants.len() }

Prevention

When it happens

Trigger: A decision-tree check stores a constructor index captured before the environment's variant list changed (re-ordering, filtering, or registration of fewer variants), so `get(*index)` returns None.

Common situations: Hit by compiler contributors after changing variant registration order, dropping unreachable variants, or when module recompilation mixes stale indices with a rebuilt environment.

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/d688315de4cd0b50. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/exhaustiveness/missing_patterns.rs:189

            RuntimeCheck::Variant {
                index,
                fields,
                labels,
                ..
            } => {
                let (module, name) = variable
                    .type_
                    .named_type_name()
                    .expect("Should be a named type");

                let name = self
                    .environment
                    .get_constructors_for_type(&module, &name)
                    .expect("Custom type constructor must have custom type kind")
                    .variants
                    .get(*index)
                    .expect("Custom type constructor exist for type")
                    .name
                    .clone();

                let fields = fields
                    .iter()
                    .enumerate()
                    .map(|(index, variable)| VariantField {
                        label: labels.get(&index).cloned(),
                        variable: variable.clone(),
                    })
                    .collect();

                Term::Variant {
                    variable,
                    name,
                    module,
                    fields,
                }

View on GitHub (pinned to 15b07c7830)