{"record":{"id":"20dc7b45ef40013e","repo":"BoundaryML/baml","slug":"field-access-on-non-map-class-at","errorCode":null,"errorMessage":"field access on non-map/class at {:?}","messagePattern":"field access on non-map/class at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-compiler/src/thir/interpret.rs","lineNumber":2055,"sourceCode":"                        base,\n                        scopes,\n                        thir,\n                        run_llm_function,\n                        watch_handler,\n                        function_name,\n                    )\n                    .await?,\n                )?;\n                match b.clone() {\n                    BamlValueWithMeta::Map(m, _) => {\n                        let v = m.get(field).context(\"missing field\")?;\n                        EvalValue::Value(v.clone())\n                    }\n                    BamlValueWithMeta::Class(_, m, _) => {\n                        let v = m.get(field).context(\"missing field\")?;\n                        EvalValue::Value(v.clone())\n                    }\n                    _ => bail!(\"field access on non-map/class at {:?}\", meta.0),\n                }\n            }\n            Expr::ClassConstructor { name, fields, meta } => {\n                let mut field_map: BamlMap<String, BamlValueWithMeta<ExprMetadata>> =\n                    BamlMap::new();\n\n                for field in fields {\n                    match field {\n                        ClassConstructorField::Named { name, value } => {\n                            field_map.insert(\n                                name.clone(),\n                                expect_value(\n                                    evaluate_expr(\n                                        value,\n                                        scopes,\n                                        thir,\n                                        run_llm_function,\n                                        watch_handler,","sourceCodeStart":2037,"sourceCodeEnd":2073,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-compiler/src/thir/interpret.rs#L2037-L2073","documentation":"For a field-access expression `base.field`, the interpreter only supports Map and Class base values; a missing field on those yields \"missing field\", but any other base type (list, string, scalar) throws \"field access on non-map/class at {:?}\". Dot access is reserved for structural values.","triggerScenarios":"Using dot syntax on a value that evaluates to a list, string, int, bool, or null — e.g. `my_list.first`, `\"text\".length` — instead of a map or class instance.","commonSituations":"Assuming strings or lists have properties/methods like in other languages; accessing a field on what you thought was a class but the LLM/parse produced a scalar; chaining off a function call that returns the wrong type.","solutions":["Check the base value's actual type and use the correct access form (index for lists, direct value for scalars)","If expecting a class, ensure the expression constructs/returns that class (e.g. correct ClassConstructor call)","For lists, index elements first, then access fields on the element","Validate LLM/parse output shape so the value is a class/map as expected"],"exampleFix":"// before\nlet x = my_list.name // field access on non-map/class\n// after\nlet x = my_list[0].name","handlingStrategy":"type-guard","validationCode":"// Confirm the value supports field access before using dot syntax\nfunction assertFieldAccess(v: unknown, field: string): void {\n  if (v === null || typeof v !== \"object\" || Array.isArray(v))\n    throw new Error(`Cannot access field '${field}' on ${Array.isArray(v) ? \"list\" : typeof v}`);\n}","typeGuard":"function isStruct(v: unknown): v is Record<string, unknown> {\n  return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  return evalBaml(fieldExpr);\n} catch (e) {\n  if (String(e).includes(\"field access on non-map/class\")) {\n    throw new Error(\"Dot access requires a map or class — check the base value's type\");\n  }\n  throw e;\n}","preventionTips":["Validate parsed/LLM output shapes so fields live on classes/maps as expected","Index list elements first, then access fields on the element","Do not expect string/list methods or properties in BAML expressions","Check function return types before chaining field access onto calls"],"tags":["interpreter","field-access","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}