{"record":{"id":"9498abd864337902","repo":"PRQL/prql","slug":"parameter-rolling-expected-a-number-found-fou","errorCode":null,"errorMessage":"parameter `rolling`: expected a number, found {found}","messagePattern":"parameter `rolling`: expected a number, found (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"prqlc/prqlc/src/semantic/resolver/transforms.rs","lineNumber":180,"sourceCode":"\n                let expanding = {\n                    let as_bool = expanding.kind.as_literal().and_then(|l| l.as_boolean());\n\n                    *as_bool.ok_or_else(|| {\n                        Error::new(Reason::Expected {\n                            who: Some(\"parameter `expanding`\".to_string()),\n                            expected: \"a boolean\".to_string(),\n                            found: write_pl(expanding.clone()),\n                        })\n                        .with_span(expanding.span)\n                    })?\n                };\n\n                let rolling = {\n                    let as_int = rolling.kind.as_literal().and_then(|x| x.as_integer());\n\n                    *as_int.ok_or_else(|| {\n                        Error::new(Reason::Expected {\n                            who: Some(\"parameter `rolling`\".to_string()),\n                            expected: \"a number\".to_string(),\n                            found: write_pl(rolling.clone()),\n                        })\n                        .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)?","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/PRQL/prql/blob/e164e249b99485890036eb60f57c37520379b240/prqlc/prqlc/src/semantic/resolver/transforms.rs#L162-L198","documentation":"The `rolling` parameter of the `window` transform must be an integer literal specifying the rolling window size. When the resolver cannot read it as an integer literal (it is a float, string, boolean, or expression), it throws this error naming the parameter and printing the found expression.","triggerScenarios":"Calling `window rolling:<expr>` where the argument is not an integer literal — e.g. `rolling:3.5`, `rolling:\"3\"`, `rolling:n` for a variable, or `rolling:2+1`.","commonSituations":"Quoting the window size; using a float; trying to parameterize the window with a variable (not supported at compile time); copying SQL `ROWS BETWEEN` syntax.","solutions":["Pass a plain integer literal, e.g. `rolling:3`","Remove quotes around numeric values","Inline any variable value as a literal, since window sizes are resolved at compile time"],"exampleFix":"// before\nwindow rolling:\"3\" (sum amount)\n// after\nwindow rolling:3 (sum amount)","handlingStrategy":"validation","validationCode":"const rolling = 3;\nif (!Number.isInteger(rolling)) {\n  throw new Error(\"rolling must be an integer literal\");\n}","typeGuard":"const isIntLit = (v) => typeof v === \"number\" && Number.isInteger(v);","tryCatchPattern":"try { prql_compile(query); } catch (e) { if (e.message.includes(\"parameter `rolling`\")) { /* replace rolling arg with an integer literal */ } else { throw e; } }","preventionTips":["Pass a bare integer like rolling:3","No strings or floats for window size","Inline variable values — window sizes are resolved at compile time"],"tags":["prql","window","type-mismatch","validation"],"backgroundTag":"type-mismatch","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"}