getredash/redash · error · QueryParseError
'pagination.path' should be a string
Error message
'pagination.path' should be a string
What it means
UrlPagination validates that the optional 'pagination.path' setting is a string; it defaults to '_links.next.href' (JSON API style). A non-string path (number, object, list) means the config is malformed and the runner cannot locate the next-page URL in responses.
Source
Thrown at redash/query_runner/json_ds.py:251
@staticmethod
def from_config(configuration, pagination):
if not isinstance(pagination, dict) or not isinstance(pagination.get("type"), str):
raise QueryParseError("'pagination' should be an object with a `type` property")
if pagination["type"] == "url":
return UrlPagination(pagination)
elif pagination["type"] == "token":
return TokenPagination(pagination)
raise QueryParseError("Unknown 'pagination.type' {}".format(pagination["type"]))
class UrlPagination(RequestPagination):
def __init__(self, pagination):
self.path = pagination.get("path", "_links.next.href")
if not isinstance(self.path, str):
raise QueryParseError("'pagination.path' should be a string")
def next(self, url, request_options, response):
next_url = _apply_path_search(response, self.path, "")
if not next_url:
return False, None, request_options
next_url = urljoin(url, next_url)
return True, next_url, request_options
class TokenPagination(RequestPagination):
def __init__(self, pagination):
self.fields = pagination.get("fields", ["next_page_token", "page_token"])
if not isinstance(self.fields, list) or len(self.fields) != 2:
raise QueryParseError("'pagination.fields' should be a list of 2 field names")
def next(self, url, request_options, response):
next_token = _apply_path_search(response, self.fields[0], "")View on GitHub (pinned to ca79fe988d)
Solutions
- Make pagination.path a dotted JSON path string, e.g. "_links.next.href" or "data.next_url"
- Omit path to use the default '_links.next.href'
- Verify the path actually exists in the API response payload
Example fix
// before
{"pagination": {"type": "url", "path": ["links", "next"]}}
// after
{"pagination": {"type": "url", "path": "links.next"}} Defensive patterns
Strategy: validation
Validate before calling
path = cfg.get('pagination', {}).get('path', '_links.next.href')
assert isinstance(path, str) and path, 'pagination.path must be a dotted string path' Type guard
def valid_path(p: dict) -> bool:
path = p.get('path', '_links.next.href')
return isinstance(path, str) and len(path) > 0 Prevention
- Express JSON pointer paths as dotted strings, never arrays
- Omit path when the API follows JSON API _links conventions
When it happens
Trigger: Supplying {"pagination": {"type": "url", "path": 123}} or "path": ["next"] — any non-string value for pagination.path.
Common situations: Developer passes a JSON pointer array or a dotted path with a typo in type, or a YAML/JSON templating system injects a number/boolean into the field.
Related errors
- 'pagination.fields' should be a list of 2 field names
- Unknown 'pagination.type' {}
- {} did not change; possible misconfiguration
- 'pagination' should be an object with a `type` property
- '{0}' is not a supported column type
AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28).
Data as JSON: /api/errors/18870d67b13d5926.
Report an issue: GitHub.