gleam-lang/gleam · error
case with no subjects
Error message
case with no subjects
What it means
When a `case` expression being compiled has no branches, the compiler still needs at least one subject variable to split the decision tree on; `subject_variables.first().expect("case with no subjects")` panics if the expression has zero subjects. This signals a malformed (subject-less) case expression reached the exhaustiveness compiler.
Solutions
- Ensure every case expression reaching compilation has at least one subject; fix the producer of the malformed AST node
- If a subject-less case is legitimate, handle it before calling `split_and_compile_with_pivot_var` (e.g. return a catch-all decision)
- Trace with a backtrace which pass created the empty-subject case and add validation there
- End users: file a compiler bug with the triggering source code
Example fix
// before
let var = self.subject_variables.first().expect("case with no subjects").clone();
// after
let var = self.subject_variables.first().cloned().unwrap_or_else(|| panic!("compiling case with zero subjects; frontend should have rejected this")); Defensive patterns
Strategy: validation
Validate before calling
if branches.is_empty() && subject_variables.is_empty() {
return Err(Error::CaseExpressionMissingSubjects);
} Type guard
fn compilable(case: &CaseToCompile) -> bool { !case.subject_variables.is_empty() } Prevention
- Reject subject-less case expressions in the typechecker
- Validate the AST before lowering to exhaustiveness structures
- Add an invariant test that every CompileCaseResult has >= 1 subject
When it happens
Trigger: Compiling `CompileCaseResult`/case compilation where `branches` is empty AND the original case expression had no subjects (e.g. `case` with no arguments produced by a buggy earlier pass).
Common situations: Encountered when working on Gleam compiler internals: a desugaring or codegen pass constructing a case expression without subjects, or fuzz input where subject validation was skipped.
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
- Custom type constructor exist for type
- Custom type constructor must have custom type kind
- Should be a named type
- wrong number of subject variables for pattern
- wrong number of subjects
AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14).
Data as JSON: /api/errors/8881ec5832fa9ac1.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/exhaustiveness.rs:3700
pub fn add_pattern(&mut self, pattern: &TypedPattern) {
let pattern = self.register(pattern);
let var = self
.subject_variables
.first()
.expect("wrong number of subject variables for pattern");
let branch = Branch::new(self.number_of_clauses, 0, vec![var.is(pattern)], false);
self.number_of_clauses += 1;
self.branches.push(branch);
}
pub fn compile(self, env: &Environment<'_>) -> CompileCaseResult {
let mut compiler = Compiler::new(env, self.variable_id, self.patterns);
let decision = if self.branches.is_empty() {
let var = self
.subject_variables
.first()
.expect("case with no subjects")
.clone();
compiler.split_and_compile_with_pivot_var(var, VecDeque::new())
} else {
compiler.compile(self.branches.into())
};
CompileCaseResult {
diagnostics: compiler.diagnostics,
compiled_case: CompiledCase {
tree: decision,
subject_variables: self.subject_variables,
},
}
}
/// Registers a typed pattern (and all its sub-patterns) into this
/// `CaseToCompile`'s pattern arena, returning an id to get the pattern back.View on GitHub (pinned to 49f8762da5)