BoundaryML/baml · error

field assignment on non-map/class

Error message

field assignment on non-map/class

What it means

When assigning to a field access target like `obj.field = value`, the interpreter only supports bases that evaluate to a `Map` (or class-like map value). If the base value is any other type (string, int, list, etc.), it bails with `field assignment on non-map/class`. Note it also errors if the named field does not yet exist on the map.

Solutions

  1. Verify the base value is actually a map/class with the target field present before assigning
  2. Add the field at map construction time instead of assigning to a missing key
  3. Inspect the value's runtime type (print/log it) to confirm it is a Map
  4. If mutating other types is needed, rebuild the value with the updated field rather than in-place assignment

Example fix

// before
let cfg = {};
cfg.name = "x"; // field `name` not found for assignment
// after
let cfg = { name: "x" };
cfg.name = "y"; // ok: key exists on a map
Defensive patterns

Strategy: type-guard

Validate before calling

// verify the base is a map containing the field before assigning
// (conceptual host-side check)
assert matches!(value, BamlValue::Map(_));

Type guard

fn is_map_with_field(v: &BamlValue, field: &str) -> bool {
    match v { BamlValue::Map(m) => m.contains_key(field), _ => false }
}

Try / catch

// host-side
match interp_result {
    Err(e) if e.to_string().contains("field assignment on non-map") => {
        // rebuild value as a map with the field instead of mutating
    }
    other => other?,
}

Prevention

When it happens

Trigger: `x.f = v` where `x` evaluates to a non-map BAML value, or where the map `x` has no key `f` (the inner `field \`f\` not found for assignment` context is attached).

Common situations: Treating a string/number result as an object; assuming class instances support direct field mutation when the runtime models them as maps without that key; JSON input missing the field you try to overwrite.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/4d97b843ac9c5a1a. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml-compiler/src/thir/interpret.rs:1495

                        function_name,
                    )
                    .await?,
                )?;

                match &mut base_value {
                    BamlValueWithMeta::Class(_, fields, _) => {
                        let entry = fields
                            .get_mut(field)
                            .with_context(|| format!("field `{field}` not found for assignment"))?;
                        *entry = value_to_assign.clone();
                    }
                    BamlValueWithMeta::Map(fields, _) => {
                        let entry = fields
                            .get_mut(field)
                            .with_context(|| format!("field `{field}` not found for assignment"))?;
                        *entry = value_to_assign.clone();
                    }
                    _ => bail!("field assignment on non-map/class"),
                }

                value_to_assign = base_value;
                current_expr = base.as_ref();
            }
            Expr::ArrayAccess { base, index, meta } => {
                let mut base_value = expect_value(
                    evaluate_expr(
                        base,
                        scopes,
                        thir,
                        run_llm_function,
                        watch_handler,
                        function_name,
                    )
                    .await?,
                )?;
                let index_value = expect_value(

View on GitHub (pinned to bd85ce9dee)