gleam-lang/gleam · error
unknown pattern id
Error message
unknown pattern id
What it means
This is a Rust panic from an `expect` on a HashMap lookup in the Gleam compiler's exhaustiveness checker (`decision::reachability` pattern store). The compiler tried to fetch a Pattern by its arena Id, and the id was not present in the interner map. It is an internal invariant violation, not something pattern-matching user code did wrong semantically.
Solutions
- Ensure every `Id<Pattern>` you use was produced by the same `register`/pattern-store instance that is doing the lookup.
- Check for off-by-one or copied ids: regenerate the id via `register` instead of reusing a stale one.
- Replace `.expect` with a graceful error (Error::Bug / todo) if the id can legitimately be absent, and file a Gleam compiler bug with the crashing module if it is not your code.
Example fix
// before
let pattern = self.patterns.get_mut(pattern_id).expect("unknown pattern id");
// after
let pattern = self.patterns.get_mut(pattern_id).unwrap_or_else(|| {
panic!("unknown pattern id {:?} in store of {} patterns", pattern_id, self.patterns.len())
}); Defensive patterns
Strategy: validation
Validate before calling
// Before relying on an Id<Pattern>, confirm it exists in the store: assert!(store.patterns.contains_key(&pattern_id), "pattern id not registered in this store");
Type guard
fn is_registered(store: &PatternStore, id: Id<Pattern>) -> bool {
store.patterns.contains_key(&id)
} Try / catch
// Rust panics cannot be caught idiomaticly; catch at the binary boundary:
let result = std::panic::catch_unwind(|| compile_case(module));
match result { Ok(v) => v, Err(_) => report_bug("unknown pattern id") } Prevention
- Never carry Id<Pattern> values across two exhaustiveness-checker instances.
- Always obtain ids from `register`, never synthesize or copy them.
- Convert expects into typed Bug errors in compiler PRs.
When it happens
Trigger: Calling `DecisionReachability::pattern(pattern_id)` (directly or via `register`/check building) with an `Id<Pattern>` that was never inserted into `self.patterns`, or that came from a different pattern-store instance (e.g. ids created by another compilation of the same function).
Common situations: Developers hit this while hacking on the Gleam compiler itself: refactoring how patterns are registered, reusing pattern ids across two exhaustiveness runs, or building a `RuntimeCheckKind` from patterns that were never passed through `register`.
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
- at least one choice
- bit array compilation with no choice
- check to already be a choice
- empty bit array test
- no unconditional patterns left
AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14).
Data as JSON: /api/errors/d9b7320c68972b44.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/exhaustiveness.rs:2401
impl<'a> Compiler<'a> {
fn new(environment: &'a Environment<'a>, variable_id: usize, patterns: Arena<Pattern>) -> Self {
Self {
environment,
patterns,
variable_id,
diagnostics: Diagnostics {
missing: false,
reachable: HashSet::new(),
match_impossible_variants: HashSet::new(),
match_impossible_segments: HashMap::new(),
},
}
}
fn pattern(&mut self, pattern_id: Id<Pattern>) -> &mut Pattern {
self.patterns
.get_mut(pattern_id)
.expect("unknown pattern id")
}
/// Returns a new fresh variable (i.e. guaranteed to have a unique `variable_id`)
/// with the given type.
///
fn fresh_variable(&mut self, type_: Arc<Type>) -> Variable {
let var = Variable::new(self.variable_id, type_);
self.variable_id += 1;
var
}
fn mark_as_reached(&mut self, branch: &Branch) {
let _ = self
.diagnostics
.reachable
.insert((branch.clause_index, branch.alternative_index));
}
View on GitHub (pinned to 49f8762da5)