getredash/redash · warning · QueryParseError
Only GET or POST methods are allowed.
Error message
Only GET or POST methods are allowed.
What it means
The JSON URL runner supports only GET and POST requests. method defaults to 'get'; any other value (put, delete, patch, or a typo like 'GET ' with whitespace/caps) fails the `method not in ('get','post')` check and raises QueryParseError.
Source
Thrown at redash/query_runner/json_ds.py:192
method = query.get("method", "get")
request_options = project(query, ("params", "headers", "data", "auth", "json", "verify"))
fields = query.get("fields")
path = query.get("path")
if "pagination" in query:
pagination = RequestPagination.from_config(self.configuration, query["pagination"])
else:
pagination = None
if isinstance(request_options.get("auth", None), list):
request_options["auth"] = tuple(request_options["auth"])
elif self.configuration.get("username") or self.configuration.get("password"):
request_options["auth"] = (self.configuration.get("username"), self.configuration.get("password"))
if method not in ("get", "post"):
raise QueryParseError("Only GET or POST methods are allowed.")
if fields and not isinstance(fields, list):
raise QueryParseError("'fields' needs to be a list.")
results, error = self._get_all_results(query["url"], method, path, pagination, **request_options)
return parse_json(results, fields), error
def _get_all_results(self, url, method, result_path, pagination, **request_options):
"""Get all results from a paginated endpoint."""
base_url = self.configuration.get("base_url")
url = urljoin(base_url, url)
results = []
has_more = True
while has_more:
response, error = self._get_json_response(url, method, **request_options)
has_more = False
View on GitHub (pinned to ca79fe988d)
Solutions
- Change method to get or post (omit the key entirely for GET)
- If the API needs PUT/DELETE, proxy the call or use the Python query runner to make the request
Example fix
# before method: put # after method: post
Defensive patterns
Strategy: validation
Validate before calling
def method_is_supported(q: dict) -> bool:
return q.get("method", "get").lower() in ("get", "post") Type guard
def is_valid_json_ds_query(q: str) -> bool:
try:
parsed = yaml.safe_load(q)
except yaml.YAMLError:
return False
if not isinstance(parsed, dict) or "url" not in parsed:
return False
return str(parsed.get("method", "get")).lower() in ("get", "post") Prevention
- Use only get/post (lowercase, no whitespace)
- Omit method for GET requests
- Route PUT/DELETE needs through a proxy or the Python runner
When it happens
Trigger: Setting method: put / method: delete / method: patch in the query YAML, or a capitalized/whitespace variant like 'Get' that doesn't match the lowercase tuple.
Common situations: Trying REST APIs that require PUT/DELETE, or copying curl examples that use those verbs.
Related errors
- Query is empty.
- Query should be a YAML object describing the URL to query.
- Can't mix mcf: and ga: metrics.
- Can't mix mcf: and ga: dimensions.
- Couldn't find path {} in response.
AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28).
Data as JSON: /api/errors/8eed3b6574681c7d.
Report an issue: GitHub.