BoundaryML/baml · error

env.get argument must be a string

Error message

env.get argument must be a string

What it means

`env.get` evaluates its single argument and requires the resulting BAML value to be a `String`. Passing any other type (int, bool, list, map) bails with `env.get argument must be a string`, since environment variable names are looked up as string keys in the `__env_vars__` map.

Source

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

                        if args.len() != 1 {
                            bail!("env.get expects exactly one argument");
                        }

                        let key_val = expect_value(
                            evaluate_expr(
                                &args[0],
                                scopes,
                                thir,
                                run_llm_function,
                                watch_handler,
                                function_name,
                            )
                            .await?,
                        )?;

                        let key = match key_val {
                            BamlValueWithMeta::String(value, _) => value,
                            _ => bail!("env.get argument must be a string"),
                        };

                        let env_map = lookup(scopes, "__env_vars__")
                            .ok_or_else(|| anyhow!("environment context missing"))?;

                        let map = match env_map {
                            BamlValueWithMeta::Map(ref entries, _) => entries,
                            _ => bail!("environment context corrupted"),
                        };

                        if let Some(value) = map.get(&key) {
                            return Ok(EvalValue::Value(value.clone()));
                        } else {
                            bail!("Environment variable '{}' not found", key);
                        }
                    }
                }

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Pass a string literal, e.g. `env.get("MY_VAR")`
  2. Convert the value to a string before passing it to `env.get`
  3. Check that any variable used as the key actually holds a string at runtime
  4. Add a guard/`String()` conversion around dynamically computed keys

Example fix

// before
let v = env.get(42);
// after
let v = env.get("PORT");
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure the key is a string before calling env.get
let key = "PORT"; // string literal
let v = env.get(key);

Type guard

fn is_string(v: &BamlValue) -> bool { matches!(v, BamlValue::String(_)) }

Try / catch

// host-side
match result {
    Err(e) if e.to_string().contains("argument must be a string") => {
        // stringify the argument and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: `env.get(123)` or `env.get(someNonStringValue)` — the key expression evaluates to a non-string BamlValue.

Common situations: Passing an integer constant or enum instead of a quoted name; the argument expression resolving to null/other type at runtime; forgetting quotes around the variable name.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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