{"record":{"id":"384ef60716507c44","repo":"getredash/redash","slug":"page-must-be-positive-integer","errorCode":null,"errorMessage":"Page must be positive integer.","messagePattern":"Page must be positive integer\\.","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"redash/handlers/base.py","lineNumber":84,"sourceCode":"        if f not in req:\n            abort(400)\n\n\ndef get_object_or_404(fn, *args, **kwargs):\n    try:\n        rv = fn(*args, **kwargs)\n        if rv is None:\n            abort(404)\n    except NoResultFound:\n        abort(404)\n    return rv\n\n\ndef paginate(query_set, page, page_size, serializer, **kwargs):\n    count = query_set.count()\n\n    if page < 1:\n        abort(400, message=\"Page must be positive integer.\")\n\n    if (page - 1) * page_size + 1 > count > 0:\n        abort(400, message=\"Page is out of range.\")\n\n    if page_size > 250 or page_size < 1:\n        abort(400, message=\"Page size is out of range (1-250).\")\n\n    results = query_set.paginate(page, page_size)\n\n    # support for old function based serializers\n    if isclass(serializer):\n        items = serializer(results.items, **kwargs).serialize()\n    else:\n        items = [serializer(result) for result in results.items]\n\n    return {\"count\": count, \"page\": page, \"page_size\": page_size, \"results\": items}\n\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/handlers/base.py#L66-L102","documentation":"Raised by the shared paginate() helper in redash/handlers/base.py when the requested page number is less than 1. All paginated Redash list endpoints (queries, dashboards, alerts, etc.) route through this helper, so any request with page=0 or a negative page value is rejected with HTTP 400.","triggerScenarios":"Calling any list endpoint with ?page=0, ?page=-1, or a non-numeric page coerced to a value below 1 (e.g. ?page=abc handled upstream as 0). Also passing page as an empty string default when a caller omits required parameters.","commonSituations":"Client code computing page from an offset (offset/page_size) that yields 0 for the first batch instead of 1; UI components sending a 0-based page index to a 1-based API.","solutions":["Use 1-based page numbers: the first page is page=1, not page=0.","If computing from an offset, use page = offset // page_size + 1.","Validate/clamp page >= 1 before sending the request."],"exampleFix":"# before\nresp = client.get('/api/queries?page=0&page_size=25')\n\n# after\nresp = client.get('/api/queries?page=1&page_size=25')","handlingStrategy":"validation","validationCode":"page = max(1, int(page_arg))\nparams = {'page': page, 'page_size': 25}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat Redash pagination as 1-based everywhere in the client.","Centralize query-string building for paginated calls so the clamp lives in one place."],"tags":["pagination","bad-request","redash","api"],"backgroundTag":"pagination-page-out-of-range","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}