PRQL/prql · error · Error

`take`: expected int or range, found

Error message

`take`: expected int or range, found {found}

What it means

The `take` transform's argument is resolved and must be either an integer literal or a range expression. `try_restrict_range` attempts to normalize the argument into a Range; if the expression is neither (e.g. a string, list, tuple, or unresolved identifier), this error is thrown naming `take` as the context.

Solutions

  1. Pass a plain int (`take 10`) or a range (`take 5..15`)
  2. Convert the value to an int before passing it to take
  3. Remove quotes/braces around the argument

Example fix

// before
take "10"
// after
take 10
Defensive patterns

Strategy: validation

Validate before calling

function validateTakeArg(v) {
  const isInt = (x) => typeof x === "number" && Number.isInteger(x) && x >= 0;
  const ok = isInt(v) || (Array.isArray(v) && v.length === 2 && v.every(isInt) && v[0] <= v[1]);
  if (!ok) throw new Error("take requires an int or range like a..b");
}

Type guard

function isIntOrRange(v) {
  return Number.isInteger(v) ||
    (Array.isArray(v) && v.length === 2 && v.every(n => Number.isInteger(n)));
}

Try / catch

try {
  compile(query);
} catch (e) {
  if (e.message.includes("`take`") && e.message.includes("int or range")) {
    console.error("Pass take 10 or take 5..15 — no strings, tuples, or untyped variables.");
  } else { throw e; }
}

Prevention

When it happens

Trigger: `take "10"`, `take [1,2]`, `take x` where `x` is not an int/range at resolve time, or `take` applied to a named argument.

Common situations: Passing user-supplied values of the wrong type, quoting the number, or passing a tuple of counts instead of a range `a..b`.

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/cfad4cd20b0b4823. Report an issue: GitHub.

Appendix: source

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

                        ColumnSort { direction, column }
                    })
                    .collect();

                (TransformKind::Sort { by }, tbl)
            }
            "take" => {
                let [expr, tbl] = unpack::<2>(func.args);

                let range = if let ExprKind::Literal(Literal::Integer(n)) = expr.kind {
                    range_from_ints(None, Some(n))
                } else {
                    match try_restrict_range(expr) {
                        Ok((start, end)) => Range {
                            start: restrict_null_literal(start).map(Box::new),
                            end: restrict_null_literal(end).map(Box::new),
                        },
                        Err(expr) => {
                            return Err(Error::new(Reason::Expected {
                                who: Some("`take`".to_string()),
                                expected: "int or range".to_string(),
                                found: write_pl(expr.clone()),
                            })
                            // Possibly this should refer to the item after the `take` where
                            // one exists?
                            .with_span(expr.span));
                        }
                    }
                };

                (TransformKind::Take { range }, tbl)
            }
            "join" => {
                let [side, with, filter, tbl] = unpack::<4>(func.args);

                let side = {
                    let span = side.span;

View on GitHub (pinned to e164e249b9)