BoundaryML/baml · error
array access on non-list at
Error message
array access on non-list at {:?} What it means
For an index expression `expr[i]`, the interpreter requires the base to evaluate to a BamlValueWithMeta::List. Anything else (map, class, string, scalar) throws "array access on non-list at {:?}". Bracket indexing in BAML only works on lists.
Solutions
- Confirm the base expression actually produces a list (e.g. from a map or split call)
- For maps/classes use key/field access (`m.key` or `m["key"]` semantics supported by your construct) instead of integer indexing
- If the value may be a single item, wrap it in a list before indexing or handle both cases
- Check upstream parsing/LLM output shape — the value may have arrived as a non-list
Example fix
// before let first = my_map[0] // array access on non-list // after let first = my_map.first_key // or use a list: let items = [1,2]; items[0]
Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm the value is an array before indexing
function assertList(v: unknown): unknown[] {
if (!Array.isArray(v)) throw new Error("Expected a list before [index] access");
return v;
} Type guard
function isList<T>(v: unknown): v is T[] {
return Array.isArray(v);
} Try / catch
try {
return evalBaml(indexExpr);
} catch (e) {
if (String(e).includes("array access on non-list")) {
throw new Error("Use field/key access for maps and classes; [i] works only on lists");
}
throw e;
} Prevention
- Know the shape of values returned by LLM outputs/parsers before indexing
- Use dot/field access for maps and classes, brackets only for lists
- Wrap possibly-single values into arrays before indexing
- Add schema validation on parsed outputs to guarantee list types
When it happens
Trigger: Using `value[index]` where value evaluates to a map, class instance, or scalar rather than a list, during array-access handling in evaluate_expr_with_context.
Common situations: Indexing into a map with bracket syntax instead of key access (`m["key"]` vs field access); assuming a string is indexable; a variable that was expected to be a list but is null or a single value after an LLM/parse step.
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
- index not int at
- array assignment on non-list value at
- attempted to call non-function
- bitwise ^= requires integer operands
- bitwise |= requires integer operands
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/4bb833b687e9d4be.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:2025
watch_handler,
function_name,
)
.await?,
)?;
let i = expect_value(
evaluate_expr(
index,
scopes,
thir,
run_llm_function,
watch_handler,
function_name,
)
.await?,
)?;
let arr = match b.clone() {
BamlValueWithMeta::List(v, _) => v,
_ => bail!("array access on non-list at {:?}", meta),
};
let idx = match i {
BamlValueWithMeta::Int(ii, _) => ii as usize,
_ => bail!("index not int at {:?}", meta),
};
let v = arr.get(idx).cloned().context("index out of bounds")?;
EvalValue::Value(v.clone())
}
Expr::FieldAccess { base, field, meta } => {
let b = expect_value(
evaluate_expr(
base,
scopes,
thir,
run_llm_function,
watch_handler,
function_name,
)View on GitHub (pinned to bd85ce9dee)