PRQL/prql · error · Error
take: expected a positive int range, found
Error message
take: expected a positive int range, found {range_display} What it means
`take` accepts either a positive integer or a positive integer range (`start..end`). During lowering the range bounds are validated; if either bound is not a valid non-negative integer (negative, non-int, or the range is inverted/invalid), this error is thrown showing the offending range.
Solutions
- Ensure both bounds are non-negative integers
- Order the range so start <= end (e.g. `take 0..10`)
- Clamp computed bounds: `take [offset | max 0, end]` style logic before passing to take
- Use plain `take n` when you only need a count
Example fix
// before take -5..10 // after take 0..10
Defensive patterns
Strategy: validation
Validate before calling
function validateTake(n) {
if (typeof n === "number") {
if (!Number.isInteger(n) || n < 0) throw new Error("take requires a positive int");
} else if (Array.isArray(n) && n.length === 2) {
const [s, e] = n;
if (!Number.isInteger(s) || !Number.isInteger(e) || s < 0 || e < s) throw new Error(`take requires a positive int range, got ${s}..${e}`);
}
} Type guard
function isValidTakeArg(v) {
if (Number.isInteger(v)) return v >= 0;
return Array.isArray(v) && v.length === 2 &&
v.every(Number.isInteger) && v[0] >= 0 && v[0] <= v[1];
} Try / catch
try {
compile(query);
} catch (e) {
if (e.message.includes("take") && e.message.includes("positive int range")) {
console.error("Clamp take bounds to non-negative ints and order start<=end.");
} else { throw e; }
} Prevention
- Clamp computed offsets to >= 0
- Ensure range start <= end
- Pass integers, not floats or strings, to take
When it happens
Trigger: `take -5..10`, `take 10..1` (start greater than end), `take 1.5`, or a variable bound that is not a positive int at that point.
Common situations: Pagination code computing offsets that can go negative, swapping range endpoints, or passing a float count from user input.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- `take`: expected int or range, found
- parameter `rows`: expected a range, found
- parameter `range`: expected a range, found
- {}
- Currently `lex` only works with a single source, but found…
AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09).
Data as JSON: /api/errors/3b05eeb05b9084b9.
Report an issue: GitHub.
Appendix: source
Thrown at prqlc/prqlc/src/semantic/lowering.rs:1172
let start = bound_as_int(&range.start);
let end = bound_as_int(&range.end);
let start_ok = if let Some(start) = start {
start.map(|s| *s >= 1).unwrap_or(false)
} else {
true
};
let end_ok = if let Some(end) = end {
end.map(|e| *e >= 1).unwrap_or(false)
} else {
true
};
if !start_ok || !end_ok {
let range_display = format!("{}..{}", bound_display(start), bound_display(end));
Err(Error::new(Reason::Expected {
who: Some("take".to_string()),
expected: "a positive int range".to_string(),
found: range_display,
})
.with_span(span))
} else {
Ok(())
}
}
#[derive(Default)]
struct TableExtractor {
path: Vec<String>,
tables: Vec<(Ident, (decl::TableDecl, Option<usize>))>,
}
impl TableExtractor {View on GitHub (pinned to e164e249b9)