{"record":{"id":"0eae144601edf1c3","repo":"BoundaryML/baml","slug":"realized-union-member-template-failed-to-substitute-e","errorCode":null,"errorMessage":"realized union-member template failed to substitute: {e}","messagePattern":"realized union-member template failed to substitute: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_vm/src/package_baml/json.rs","lineNumber":884,"sourceCode":"        )),\n\n        RealizedTy::Union(members, _) => {\n            // Select the first declared member that contains the runtime value,\n            // using the same ordered, decidable membership relation as `is` and\n            // typed match arms. Serialization then remains fully type-directed:\n            // a class/media/uint8array member behaves exactly as it would outside\n            // the union, and values outside every member fail the type contract.\n            let member = members.iter().find(|member| {\n                crate::type_match::value_matches_template(\n                    vm,\n                    value,\n                    &TyTemplate::from((*member).clone()),\n                    &[],\n                )\n                // A template built from a `RealizedTy` carries no frame refs\n                // and no projections, so substitution cannot fail.\n                .unwrap_or_else(|e| {\n                    unreachable!(\"realized union-member template failed to substitute: {e}\")\n                })\n            });\n            match member {\n                Some(member) => ty_value_to_serde(vm, value, member, path),\n                None => Err(raise_serialize(\n                    vm,\n                    \"value is not a member of the union\",\n                    path,\n                    \"union\",\n                )),\n            }\n        }\n\n        RealizedTy::Resource { .. } | RealizedTy::PromptAst { .. } => Err(raise_serialize(\n            vm,\n            \"cannot serialize opaque type\",\n            path,\n            \"opaque\",","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_vm/src/package_baml/json.rs#L866-L902","documentation":"Panic in `ty_value_to_serde` when substituting a union member into a `TyTemplate` fails. Because the template is built from an already-realized `RealizedTy` it carries no frame refs or projections, so substitution is mathematically infallible; a failure means the type was not actually fully realized (e.g. it still contains unbound template variables or frame references).","triggerScenarios":"Serializing a value whose union member type still contains unresolved template variables or frame references, reached via json_to_string_typed, ty_value_to_serde recursion, or serialize_class_instance on a class with generic/tEMPLATE union fields that were not fully substituted before serialization.","commonSituations":"Serializing instances of generic BAML classes with union-typed fields where the type realization pass missed a substitution step — typically after VM/typechecker upgrades or when embedding the type APIs directly.","solutions":["Ensure types are fully realized (all template variables substituted) before calling ty_value_to_serde / json_to_string_typed.","Upgrade bex_vm — this may be a realization-pass bug for union members.","Reproduce with the smallest class/union definition and report it to baml_language maintainers.","As a workaround, serialize the field with an explicit concrete type rather than through the generic union path."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure union member types are fully realized before serialization:\nfn fully_realized(ty: &RealizedTy) -> bool {\n    !matches!(ty, RealizedTy::Var(_) | RealizedTy::FrameRef(_))\n}","typeGuard":null,"tryCatchPattern":"// Catchable only at the process level; validate realized types before ty_value_to_serde:\ndebug_assert!(fully_realized(&member_ty), \"unrealized union member reached serde\");","preventionTips":["Run the full type-realization/substitution pass before serializing generic classes.","Avoid serializing values carrying unresolved template variables.","Keep the typechecker and VM on matching versions."],"tags":["rust","generics","serialization","panic"],"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-14T11:17:12.474Z"}