{"record":{"id":"3b05eeb05b9084b9","repo":"PRQL/prql","slug":"take-expected-a-positive-int-range-found-range","errorCode":null,"errorMessage":"take: expected a positive int range, found {range_display}","messagePattern":"take: expected a positive int range, found (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"prqlc/prqlc/src/semantic/lowering.rs","lineNumber":1172,"sourceCode":"\n    let start = bound_as_int(&range.start);\n    let end = bound_as_int(&range.end);\n\n    let start_ok = if let Some(start) = start {\n        start.map(|s| *s >= 1).unwrap_or(false)\n    } else {\n        true\n    };\n\n    let end_ok = if let Some(end) = end {\n        end.map(|e| *e >= 1).unwrap_or(false)\n    } else {\n        true\n    };\n\n    if !start_ok || !end_ok {\n        let range_display = format!(\"{}..{}\", bound_display(start), bound_display(end));\n        Err(Error::new(Reason::Expected {\n            who: Some(\"take\".to_string()),\n            expected: \"a positive int range\".to_string(),\n            found: range_display,\n        })\n        .with_span(span))\n    } else {\n        Ok(())\n    }\n}\n\n#[derive(Default)]\nstruct TableExtractor {\n    path: Vec<String>,\n\n    tables: Vec<(Ident, (decl::TableDecl, Option<usize>))>,\n}\n\nimpl TableExtractor {","sourceCodeStart":1154,"sourceCodeEnd":1190,"githubUrl":"https://github.com/PRQL/prql/blob/e164e249b99485890036eb60f57c37520379b240/prqlc/prqlc/src/semantic/lowering.rs#L1154-L1190","documentation":"`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.","triggerScenarios":"`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.","commonSituations":"Pagination code computing offsets that can go negative, swapping range endpoints, or passing a float count from user input.","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"],"exampleFix":"// before\ntake -5..10\n// after\ntake 0..10","handlingStrategy":"validation","validationCode":"function validateTake(n) {\n  if (typeof n === \"number\") {\n    if (!Number.isInteger(n) || n < 0) throw new Error(\"take requires a positive int\");\n  } else if (Array.isArray(n) && n.length === 2) {\n    const [s, e] = n;\n    if (!Number.isInteger(s) || !Number.isInteger(e) || s < 0 || e < s) throw new Error(`take requires a positive int range, got ${s}..${e}`);\n  }\n}","typeGuard":"function isValidTakeArg(v) {\n  if (Number.isInteger(v)) return v >= 0;\n  return Array.isArray(v) && v.length === 2 &&\n    v.every(Number.isInteger) && v[0] >= 0 && v[0] <= v[1];\n}","tryCatchPattern":"try {\n  compile(query);\n} catch (e) {\n  if (e.message.includes(\"take\") && e.message.includes(\"positive int range\")) {\n    console.error(\"Clamp take bounds to non-negative ints and order start<=end.\");\n  } else { throw e; }\n}","preventionTips":["Clamp computed offsets to >= 0","Ensure range start <= end","Pass integers, not floats or strings, to take"],"tags":["prql","take","range"],"backgroundTag":"invalid-argument-value","analyzedSha":"e164e249b99485890036eb60f57c37520379b240","analyzedAt":"2026-09-09T12:18:38.727Z","contentChangedAt":"2026-09-09T12:18:38.727Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}