{"record":{"id":"7f7def6c146acc29","repo":"PRQL/prql","slug":"parameter-range-expected-a-range-found-found","errorCode":null,"errorMessage":"parameter `range`: expected a range, found {found}","messagePattern":"parameter `range`: expected a range, found (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"prqlc/prqlc/src/semantic/resolver/transforms.rs","lineNumber":203,"sourceCode":"                        .with_span(rolling.span)\n                    })?\n                };\n\n                let rows = {\n                    let range_tuple = try_restrict_range(rows).map_err(|expr| {\n                        Error::new(Reason::Expected {\n                            who: Some(\"parameter `rows`\".to_string()),\n                            expected: \"a range\".to_string(),\n                            found: write_pl(expr.clone()),\n                        })\n                        .with_span(expr.span)\n                    })?;\n                    into_literal_range(range_tuple)?\n                };\n\n                let range = {\n                    let range_tuple = try_restrict_range(range).map_err(|expr| {\n                        Error::new(Reason::Expected {\n                            who: Some(\"parameter `range`\".to_string()),\n                            expected: \"a range\".to_string(),\n                            found: write_pl(expr.clone()),\n                        })\n                        .with_span(expr.span)\n                    })?;\n                    into_literal_range(range_tuple)?\n                };\n\n                let (kind, start, end) = if expanding {\n                    (WindowKind::Rows, None, Some(0))\n                } else if rolling > 0 {\n                    (WindowKind::Rows, Some(-rolling + 1), Some(0))\n                } else if !range_is_empty(&rows) {\n                    (WindowKind::Rows, rows.0, rows.1)\n                } else if !range_is_empty(&range) {\n                    (WindowKind::Range, range.0, range.1)\n                } else {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/PRQL/prql/blob/e164e249b99485890036eb60f57c37520379b240/prqlc/prqlc/src/semantic/resolver/transforms.rs#L185-L221","documentation":"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.","triggerScenarios":"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.","commonSituations":"Using list/bracket syntax instead of `..` range syntax; porting SQL `RANGE BETWEEN` directly; mixing up `range:` and `rows:` parameter semantics.","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"],"exampleFix":"// before\nwindow range:[1,10] (sum amount)\n// after\nwindow range:(1..10) (sum amount)","handlingStrategy":"validation","validationCode":"const range = \"(0..10)\"; // must be a PRQL range tuple\nif (!range.startsWith(\"(\") || !range.includes(\"..\")) {\n  throw new Error(\"range must be a tuple like (start..end)\");\n}","typeGuard":"const isRangeArg = (v) => typeof v === \"object\" && v !== null && \"start\" in v && \"end\" in v;","tryCatchPattern":"try { prql_compile(query); } catch (e) { if (e.message.includes(\"parameter `range`\")) { /* convert arg to a range tuple */ } else { throw e; } }","preventionTips":["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"],"tags":["prql","window","range","validation"],"backgroundTag":"invalid-argument-format","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"}