BoundaryML/baml · error
continue statement not in loop context
Error message
continue statement not in loop context
What it means
Raised by evaluate_block when a `continue` statement's ControlFlow::Continue signal escapes to a non-loop context. `continue` is only valid inside the body of a for/while loop in BAML; if it executes in a block with no enclosing loop (such as a filter function body or a plain expression block), the interpreter bails with this message.
Solutions
- Ensure `continue` appears only inside a for/while loop body; remove it elsewhere.
- In filter/map callbacks, express skipping via the predicate or an if condition rather than continue.
- Inside a loop body but hitting this anyway: check that the continue isn't inside a nested lambda whose body has no loop.
- Upgrade BAML if you believe continue is valid in this context — this may be a scoping bug worth reporting.
Example fix
// before (BAML)
for (let n in nums) { if (n % 2 != 0) { continue; } }
// (valid in a loop; invalid in a filter lambda)
let evens = nums.filter(|n| n % 2 == 0); Defensive patterns
Strategy: validation
Validate before calling
// Static guard: `continue` must appear inside a loop body; never in lambda bodies.
if (/\bcontinue\b/.test(lambdaBodySrc)) {
throw new Error("continue is not allowed in non-loop blocks; filter first or use an if inside the loop");
} Try / catch
try {
return await bamlFn(ctx, args);
} catch (e) {
if (String(e).includes("continue statement not in loop context")) {
throw new Error("BAML source error: move `continue` inside a for loop body");
}
throw e;
} Prevention
- Use `continue` only directly inside for/while loop bodies.
- To skip items in map/filter, use the callback predicate or an if in the loop body.
- Lint BAML sources for continue outside loop contexts.
- Watch for continue inside nested lambdas — the innermost block has no loop.
When it happens
Trigger: Placing `continue` inside a BAML block that is not a loop body — e.g. a lambda/filter function, an if-else branch outside any loop, or a function body — so the Continue control-flow flag propagates uncaught to evaluate_block.
Common situations: Using `continue` to skip elements inside a map/filter callback (wrong tool — use the predicate or an if inside the loop body instead); copy-pasted loop code moved out of its loop; misunderstanding that `continue` works in any block.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- break statement not in loop context
- unsupported assign op in C-for after clause
- unsupported statement type in C-for after clause
- {0:?}
- {0}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b253a89f25b4d584.
Report an issue: GitHub.
Appendix: source
Thrown at engine/baml-compiler/src/thir/interpret.rs:1418
) -> Result<BamlValueWithMeta<ExprMetadata>>
where
F: LlmHandler<Fut>,
Fut: LlmFuture,
{
match evaluate_block_with_control_flow(
block,
scopes,
thir,
run_llm_function,
watch_handler,
function_name,
)
.await?
{
ControlFlow::Normal(val) => Ok(val),
ControlFlow::Return(val) => Ok(val),
ControlFlow::Break => bail!("break statement not in loop context"),
ControlFlow::Continue => bail!("continue statement not in loop context"),
}
}
fn declare(scopes: &mut [Scope], name: &str, value: BamlValueWithMeta<ExprMetadata>) {
if let Some(scope) = scopes.last_mut() {
scope
.variables
.insert(name.to_string(), Arc::new(Mutex::new(value)));
}
}
fn declare_with_cell(
scopes: &mut [Scope],
name: &str,
cell: Arc<Mutex<BamlValueWithMeta<ExprMetadata>>>,
) {
if let Some(scope) = scopes.last_mut() {
scope.variables.insert(name.to_string(), cell);View on GitHub (pinned to bd85ce9dee)