PRQL/prql · error · Error

parameter `expanding`: expected a boolean, found

Error message

parameter `expanding`: expected a boolean, found {found}

What it means

In the `window` transform, the `expanding` parameter must be a boolean literal (`true` or `false`). The resolver attempts to read the argument as a boolean literal and throws this error when it is any other kind of expression or literal. The found value is pretty-printed to help spot the mistake.

Solutions

  1. Pass the literal `true` or `false` for `expanding:`
  2. Remove the parameter entirely if not needed (window has defaults)
  3. Use `rolling:` with a number instead if a fixed-size window was intended

Example fix

// before
window expanding:1 (sum amount)
// after
window expanding:true (sum amount)
Defensive patterns

Strategy: validation

Validate before calling

const expanding = true;
if (typeof expanding !== "boolean") {
  throw new Error("expanding must be a boolean literal");
}

Type guard

const isBool = (v) => typeof v === "boolean";

Try / catch

try { prql_compile(query); } catch (e) { if (e.message.includes("parameter `expanding`")) { /* fix expanding arg to true/false */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling `window` with `expanding:` set to a non-boolean literal, e.g. `window expanding:1 ...`, `expanding:"yes"`, or an interpolated/computed expression instead of `true`/`false`.

Common situations: Passing 1/0 like some SQL dialects accept; quoting the value; writing `expanding` without a value so it becomes a non-boolean expression; typo'ing a variable so an expression is passed.

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 PRQL/prql@e164e249b9 (2026-09-09). Data as JSON: /api/errors/4b7d303c8bb77529. Report an issue: GitHub.

Appendix: source

Thrown at prqlc/prqlc/src/semantic/resolver/transforms.rs:167

                    // fold, so lineage and types are inferred
                    self.fold_expr(partition)?
                };
                let pipeline = self.fold_by_simulating_eval(pipeline, &partition)?;

                // unpack tbl back out
                let tbl = *partition.kind.into_transform_call().unwrap().input;

                let pipeline = Box::new(pipeline);
                (TransformKind::Group { by, pipeline }, tbl)
            }
            "window" => {
                let [rows, range, expanding, rolling, pipeline, tbl] = unpack::<6>(func.args);

                let expanding = {
                    let as_bool = expanding.kind.as_literal().and_then(|l| l.as_boolean());

                    *as_bool.ok_or_else(|| {
                        Error::new(Reason::Expected {
                            who: Some("parameter `expanding`".to_string()),
                            expected: "a boolean".to_string(),
                            found: write_pl(expanding.clone()),
                        })
                        .with_span(expanding.span)
                    })?
                };

                let rolling = {
                    let as_int = rolling.kind.as_literal().and_then(|x| x.as_integer());

                    *as_int.ok_or_else(|| {
                        Error::new(Reason::Expected {
                            who: Some("parameter `rolling`".to_string()),
                            expected: "a number".to_string(),
                            found: write_pl(rolling.clone()),
                        })
                        .with_span(rolling.span)

View on GitHub (pinned to e164e249b9)