gleam-lang/gleam · error
Should be a named type
Error message
Should be a named type
What it means
`check_to_term` converts a type-checked decision-tree `check` back into a pattern term. For constructor checks it derives the type's `(module, name)` via `named_type_name().expect("Should be a named type")`, panicking when the variable's type is not a named (custom) type — e.g. it is a function, tuple, or generic type. The invariant is that only constructor checks on named custom types reach this code path.
Solutions
- Match tuple/other check kinds explicitly before the constructor branch in `check_to_term` so only named-type constructor checks hit this code
- Verify `type_.named_type_name()` is valid by inspecting the variable's type in a debug build backtrace
- If a new type representation (e.g. unlabelled types change) broke the invariant, update the handling accordingly
- End users: file a compiler bug with the pattern-match that produces wrong/missing pattern diagnostics
Example fix
// before
let (module, name) = variable.type_.named_type_name().expect("Should be a named type");
// after
let (module, name) = variable.type_.named_type_name().unwrap_or_else(|| {
panic!("check_to_term on non-named type: {:?}", variable.type_)
}); Defensive patterns
Strategy: type-guard
Validate before calling
if variable.type_.named_type_name().is_none() {
return Err(Error::CheckOnNonNamedType);
} Type guard
let Some((module, name)) = variable.type_.named_type_name() else { return Ok(Term::Variable(variable.clone())); }; Prevention
- Match all check kinds before the constructor branch in check_to_term
- Add a debug assertion that constructor checks only carry named types
- Extend tests whenever a new check variant is added
When it happens
Trigger: `add_missing_patterns_after_check` processing a check whose subject variable has a non-named type (tuple, function type, type variable) — usually after a change to how checks are generated for tuples or parameterised types.
Common situations: Hit by Gleam compiler contributors after introducing a new check kind (e.g. tuple checks) that flows into `check_to_term` without being matched before the constructor branch.
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
- case with no subjects
- Custom type constructor exist for type
- Custom type constructor must have custom type kind
- wrong number of subject variables for pattern
- wrong number of subjects
AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14).
Data as JSON: /api/errors/524abff338b1903d.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/exhaustiveness/missing_patterns.rs:181
| RuntimeCheck::String { .. }
| RuntimeCheck::BitArray { .. }
| RuntimeCheck::StringPrefix { .. } => Term::Infinite { variable },
RuntimeCheck::Tuple { elements, .. } => Term::Tuple {
variable,
elements: elements.clone(),
},
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(),
})View on GitHub (pinned to 15b07c7830)