PRQL/prql · error · Error
parameter `range`: expected a range, found
Error message
parameter `range`: expected a range, found {found} What it means
The `range` parameter of the `window` transform expects a range (tuple of two bounds) over the window's ordering value, analogous to SQL `RANGE BETWEEN`. When `try_restrict_range` cannot reduce the argument to a range, the resolver throws this error printing the offending expression.
Solutions
- Pass a range tuple, e.g. `range:(0..10)`
- Use `..` range syntax with explicit bounds instead of brackets
- Use `rows:` if the frame should be counted in rows rather than value distance
Example fix
// before window range:[1,10] (sum amount) // after window range:(1..10) (sum amount)
Defensive patterns
Strategy: validation
Validate before calling
const range = "(0..10)"; // must be a PRQL range tuple
if (!range.startsWith("(") || !range.includes("..")) {
throw new Error("range must be a tuple like (start..end)");
} Type guard
const isRangeArg = (v) => typeof v === "object" && v !== null && "start" in v && "end" in v;
Try / catch
try { prql_compile(query); } catch (e) { if (e.message.includes("parameter `range`")) { /* convert arg to a range tuple */ } else { throw e; } } Prevention
- Use (start..end) syntax, not brackets or lists
- Distinguish range: (value distance) from rows: (row count)
- Keep range bounds as literals resolved at compile time
When it happens
Trigger: Calling `window range:<x>` where `<x>` is not a range tuple — e.g. `range:5`, `range:[1,10]`, an unquoted expression, or a range over non-literal bounds.
Common situations: Using list/bracket syntax instead of `..` range syntax; porting SQL `RANGE BETWEEN` directly; mixing up `range:` and `rows:` parameter semantics.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- parameter `rows`: expected a range, found
- parameter `expanding`: expected a boolean, found
- parameter `rolling`: expected a number, found
- take: expected a positive int range, found
- `side`: expected inner, left, right or full, found
AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09).
Data as JSON: /api/errors/7f7def6c146acc29.
Report an issue: GitHub.
Appendix: source
Thrown at prqlc/prqlc/src/semantic/resolver/transforms.rs:203
.with_span(rolling.span)
})?
};
let rows = {
let range_tuple = try_restrict_range(rows).map_err(|expr| {
Error::new(Reason::Expected {
who: Some("parameter `rows`".to_string()),
expected: "a range".to_string(),
found: write_pl(expr.clone()),
})
.with_span(expr.span)
})?;
into_literal_range(range_tuple)?
};
let range = {
let range_tuple = try_restrict_range(range).map_err(|expr| {
Error::new(Reason::Expected {
who: Some("parameter `range`".to_string()),
expected: "a range".to_string(),
found: write_pl(expr.clone()),
})
.with_span(expr.span)
})?;
into_literal_range(range_tuple)?
};
let (kind, start, end) = if expanding {
(WindowKind::Rows, None, Some(0))
} else if rolling > 0 {
(WindowKind::Rows, Some(-rolling + 1), Some(0))
} else if !range_is_empty(&rows) {
(WindowKind::Rows, rows.0, rows.1)
} else if !range_is_empty(&range) {
(WindowKind::Range, range.0, range.1)
} else {View on GitHub (pinned to e164e249b9)