{"record":{"id":"05dd3776ee7cfa4a","repo":"gleam-lang/gleam","slug":"term-must-exist","errorCode":null,"errorMessage":"Term must exist","messagePattern":"Term must exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/exhaustiveness/printer.rs","lineNumber":44,"sourceCode":"            names,\n        }\n    }\n\n    pub fn print_terms(\n        &self,\n        subjects: &[Variable],\n        terms: &[Term],\n        mapping: &HashMap<usize, usize>,\n    ) -> EcoString {\n        let mut buffer = EcoString::new();\n        for (i, subject) in subjects.iter().enumerate() {\n            if i != 0 {\n                buffer.push_str(\", \");\n            }\n\n            match mapping.get(&subject.id) {\n                Some(&index) => {\n                    let term = terms.get(index).expect(\"Term must exist\");\n                    self.print(term, terms, mapping, &mut buffer);\n                }\n                None => buffer.push('_'),\n            }\n        }\n        buffer\n    }\n\n    fn print(\n        &self,\n        term: &Term,\n        terms: &[Term],\n        mapping: &HashMap<usize, usize>,\n        buffer: &mut EcoString,\n    ) {\n        match term {\n            Term::Variant {\n                name,","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/gleam-lang/gleam/blob/15b07c783065c92bb016b1b74ed0995a5259850f/compiler-core/src/exhaustiveness/printer.rs#L26-L62","documentation":"`Printer::print_terms` formats the compiled decision tree's terms for the 'unused/match-of-patterns never reached' diagnostics. For each subject it maps the subject id to a term index and does `terms.get(index).expect(\"Term must exist\")`; it panics if a subject references a term index absent from the terms list. Subjects without a mapping are printed as `_`, so this only fails on corrupt/inconsistent mapping data.","triggerScenarios":"Calling `print_terms` with a `mapping` that contains a subject id pointing to an index >= `terms.len()` — e.g. after filtering terms without updating the mapping, or when combining a mapping built against a different term list.","commonSituations":"Seen by compiler contributors when post-processing compile case results (e.g. trimming terms for diagnostics) or when caching decision trees across environments.","solutions":["Keep `mapping` and `terms` in sync: if you filter/rebuild one, rebuild the other","Validate before printing: `mapping.values().all(|i| *i < terms.len())`","Treat missing indices like the None case (print `_`) if partial output is acceptable","If triggered by normal Gleam code, file a compiler bug with the case expression"],"exampleFix":"// before\nlet term = terms.get(index).expect(\"Term must exist\");\n// after\nlet Some(term) = terms.get(index) else {\n    buffer.push('_');\n    continue;\n};","handlingStrategy":"validation","validationCode":"if mapping.values().any(|i| *i >= terms.len()) {\n    return Err(Error::TermMappingInconsistent);\n}","typeGuard":"fn mapping_consistent(mapping: &HashMap<VariableId, usize>, terms: &[Term]) -> bool {\n    mapping.values().all(|i| *i < terms.len())\n}","tryCatchPattern":null,"preventionTips":["Rebuild mapping whenever terms are filtered or rebuilt","Consider falling back to '_' for unmapped subjects instead of panicking","Snapshot-test diagnostic printing after changing term structures"],"tags":["rust","compiler","diagnostics","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"15b07c783065c92bb016b1b74ed0995a5259850f","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}