{"record":{"id":"8b872c880ef7e233","repo":"BoundaryML/baml","slug":"exhaustive-realized-leaf-template-classification","errorCode":null,"errorMessage":"exhaustive realized-leaf template classification","messagePattern":"exhaustive realized-leaf template classification","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/baml_compiler2_emit/src/emit.rs","lineNumber":3743,"sourceCode":"            | TyTemplate::Bool { .. }\n            | TyTemplate::Null { .. }\n            | TyTemplate::Uint8Array { .. }\n            | TyTemplate::Enum(..)\n            | TyTemplate::EnumVariant(..)\n            | TyTemplate::RustType { .. }\n            | TyTemplate::Type { .. }\n            | TyTemplate::Resource { .. }\n            | TyTemplate::PromptAst { .. }\n            | TyTemplate::Void { .. }\n            | TyTemplate::TypeAlias(..)\n            | TyTemplate::Never { .. }) => {\n                // A fully-realized leaf (primitive, enum, alias, literal, ...):\n                // class-pointer identity for a `TypeAlias`, otherwise its type\n                // tag when one exactly represents the test. Tagless leaves use\n                // the canonical structural matcher instead of silently\n                // compiling to false.\n                let realized = <&RealizedTy>::try_from(other)\n                    .expect(\"exhaustive realized-leaf template classification\");\n                if let RealizedTy::TypeAlias(tn, _) = realized {\n                    if let Some(class_obj_idx) = self.class_object_index_for_type_name(tn) {\n                        let c = self\n                            .add_constant(ConstValue::Object(ObjectIndex::from_raw(class_obj_idx)));\n                        let inst = self.emit(Instruction::IsType(c));\n                        self.set_operand(inst, OperandMeta::Const(tn.display_name().to_string()));\n                    } else {\n                        emit_false(self);\n                    }\n                } else if let RealizedTy::Enum(tn, _) = realized {\n                    // Enum-pointer identity: `is Color` tests the value's enum\n                    // object, so it discriminates `Color` from `Status` - the\n                    // shared `ENUM` type tag cannot. Falls back to constant-false\n                    // if the enum object is absent (e.g. an unreferenced enum).\n                    if let Some(enum_obj_idx) = self.enum_object_index_for_type_name(tn) {\n                        let c = self\n                            .add_constant(ConstValue::Object(ObjectIndex::from_raw(enum_obj_idx)));\n                        let inst = self.emit(Instruction::IsType(c));","sourceCodeStart":3725,"sourceCodeEnd":3761,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/baml_compiler2_emit/src/emit.rs#L3725-L3761","documentation":"This panic fires in the compiler emitter while lowering a template/test expression whose right-hand side is a fully-realized leaf type (primitive, enum, alias, literal). The code intentionally calls `try_from` with `.expect` to assert that every such leaf can be converted to a `RealizedTy` for classification; hitting the panic means a new leaf variant was added to the type representation but not to the `TryFrom<&Ty> for RealizedTy` conversion, or a non-leaf type leaked into a code path reserved for realized leaves.","triggerScenarios":"Compiling a `is`/type-test template whose operand is a leaf type that the `RealizedTy::try_from` conversion does not recognize — typically after adding a new `Ty` variant without updating the conversion, or a structural/holes-carrying type reaching the leaf path.","commonSituations":"Contributors to the BAML compiler adding new type forms (new primitive kinds, literal variants, or alias wrappers) without extending `RealizedTy`; refactors that let non-realized (hole-carrying) types reach the template-classification branch.","solutions":["Extend the `TryFrom<&Ty> for RealizedTy` implementation to handle the offending leaf variant","Verify the operand reaching emit.rs:3743 is actually a realized leaf; if it carries holes, route it to the structural-matcher path instead","Check recent type-system changes for new `Ty` variants missing from the conversion","Run the template/type-test compiler tests to confirm classification coverage"],"exampleFix":"// before\nlet realized = <&RealizedTy>::try_from(other)\n    .expect(\"exhaustive realized-leaf template classification\");\n// after: handle new variant in the conversion\nimpl TryFrom<&Ty> for RealizedTy {\n    fn try_from(t: &Ty) -> Result<Self, Self::Error> {\n        // ...\n        Ty::NewLeafKind(x) => Ok(RealizedTy::NewLeafKind(x.clone())),\n        // ...\n    }\n}","handlingStrategy":"type-guard","validationCode":"fn is_realized_leaf(t: &Ty) -> bool {\n    matches!(\n        t,\n        Ty::Primitive(_) | Ty::Enum(_) | Ty::Alias(_, _) | Ty::Literal(_) | Ty::TypeAlias(_, _)\n    )\n}","typeGuard":"fn as_realized(t: &Ty) -> Option<&RealizedTy> {\n    <&RealizedTy>::try_from(t).ok()\n}","tryCatchPattern":"// Rust panics are not catchable with ?; use std::panic::catch_unwind only at a process boundary\nlet result = std::panic::catch_unwind(|| emit_template_test(node));\nmatch result {\n    Ok(Ok(out)) => out,\n    _ => report_internal_error(\"template classification failed\"),\n}","preventionTips":["Add a match-all test over Ty variants against the RealizedTy conversion in CI","Never let hole-carrying types reach the leaf-classification branch","When adding a Ty variant, grep for `RealizedTy::try_from` and update all conversion sites"],"tags":["compiler","rust","panic","type-system","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}