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

  1. Ensure both bounds are non-negative integers
  2. Order the range so start <= end (e.g. `take 0..10`)
  3. Clamp computed bounds: `take [offset | max 0, end]` style logic before passing to take
  4. 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

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


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)