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

  1. Ensure `continue` appears only inside a for/while loop body; remove it elsewhere.
  2. In filter/map callbacks, express skipping via the predicate or an if condition rather than continue.
  3. Inside a loop body but hitting this anyway: check that the continue isn't inside a nested lambda whose body has no loop.
  4. 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

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


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)