{"record":{"id":"a3df2d44036fe3c5","repo":"BoundaryML/baml","slug":"invalid-type-value","errorCode":null,"errorMessage":"Invalid type value","messagePattern":"Invalid type value","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-lib/ast/src/parser/parse_types.rs","lineNumber":173,"sourceCode":"                ));\n                // Return a Symbol type to allow type validation to continue\n                // This will trigger the \"type not found\" error in the validation pipeline\n                Some(FieldType::Symbol(\n                    FieldArity::Required,\n                    Identifier::Local(\n                        current.as_str().to_string(),\n                        diagnostics.span(current.as_span()),\n                    ),\n                    None,\n                ))\n            }\n            Rule::identifier => {\n                let identifier = parse_identifier(current.clone(), diagnostics);\n                let field_type = match current.as_str() {\n                    \"string\" | \"int\" | \"float\" | \"bool\" | \"image\" | \"audio\" | \"pdf\" | \"video\" => {\n                        FieldType::Primitive(\n                            FieldArity::Required,\n                            TypeValue::from_str(identifier.name()).expect(\"Invalid type value\"),\n                            diagnostics.span(current.as_span()),\n                            None,\n                        )\n                    }\n                    \"null\" => FieldType::Primitive(\n                        FieldArity::Optional,\n                        TypeValue::Null,\n                        diagnostics.span(current.as_span()),\n                        None,\n                    ),\n                    \"true\" => FieldType::Literal(\n                        FieldArity::Required,\n                        LiteralValue::Bool(true),\n                        diagnostics.span(current.as_span()),\n                        None,\n                    ),\n                    \"false\" => FieldType::Literal(\n                        FieldArity::Required,","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-lib/ast/src/parser/parse_types.rs#L155-L191","documentation":"An expect(\"Invalid type value\") panic in parse_base_type. The code first string-matches the identifier against known primitive names (string, int, float, bool, image, audio, pdf, video) and then calls TypeValue::from_str(...).expect(...), assuming from_str cannot fail for those names. If the match arms and TypeValue::from_str ever disagree (new alias added to one but not the other), the expect panics.","triggerScenarios":"parse_base_type parsing a Rule::identifier whose string is in the primitive match list but not recognized by TypeValue::from_str — i.e. drift between the literal match list and the TypeValue enum's FromStr impl. Not reachable from valid .bml input with matched lists.","commonSituations":"Hit during BAML development when adding a new primitive type to the match arms without updating TypeValue::from_str (or vice versa), or when case-sensitivity changes make the same literal parse differently.","solutions":["Use a standard BAML primitive type name in your .bml file (string, int, float, bool, image, audio, pdf, video) at the reported span","Check for case sensitivity: `String` vs `string` — use the lowercase canonical form","Report the input upstream if a documented type name panics — the match list and TypeValue::from_str are out of sync","When adding primitives, update both the match arms in parse_base_type and TypeValue::from_str together"],"exampleFix":"// before\nfield String\n// after\nfield string","handlingStrategy":"validation","validationCode":"const PRIMITIVES: &[&str] = &[\"string\",\"int\",\"float\",\"bool\",\"image\",\"audio\",\"pdf\",\"video\"];\nfn is_known_primitive(t: &str) -> bool {\n    PRIMITIVES.contains(&t.trim())\n}\n// call before referencing the type in .bml or invoking the parser","typeGuard":"fn as_type_value(t: &str) -> Option<&str> {\n    match t.trim() {\n        \"string\" | \"int\" | \"float\" | \"bool\" | \"image\" | \"audio\" | \"pdf\" | \"video\" => Some(t.trim()),\n        _ => None,\n    }\n}","tryCatchPattern":"std::panic::catch_unwind(|| parse_base_type(pair, &mut diagnostics))\n    .map_err(|_| diagnostics.push(\"primitive name not recognized by TypeValue::from_str\"));","preventionTips":["Use exact lowercase primitive names: string, int, float, bool, image, audio, pdf, video","Update the match list in parse_base_type and TypeValue::from_str together when adding primitives","Route unknown type names to a diagnostic (FieldType::Identifier) rather than expect","Add a unit test asserting every match-list literal round-trips through TypeValue::from_str"],"tags":["parser","rust","panic","types","enum"],"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"}