getredash/redash · warning · QueryParseError

Query should be a YAML object describing the URL to query.

Error message

Query should be a YAML object describing the URL to query.

What it means

_run_json_query requires the YAML-parsed query to be a mapping (dict). If YAML resolves to a string, list, number, or None (e.g. just a URL, or a list of endpoints), it raises QueryParseError('Query should be a YAML object describing the URL to query.').

Source

Thrown at redash/query_runner/json_ds.py:170

        self.syntax = "yaml"

    def test_connection(self):
        pass

    def run_query(self, query, user):
        query = parse_query(query)

        data, error = self._run_json_query(query)
        if error is not None:
            return None, error

        if data:
            return data, None
        return None, "Got empty response from '{}'.".format(query["url"])

    def _run_json_query(self, query):
        if not isinstance(query, dict):
            raise QueryParseError("Query should be a YAML object describing the URL to query.")

        if "url" not in query:
            raise QueryParseError("Query must include 'url' option.")

        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"):

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Rewrite as a top-level YAML mapping starting with 'url:', e.g. url: https://api.example.com/items
  2. If a list was intended, run one query per item or restructure to a single mapping

Example fix

# before
https://api.example.com/items
# after
url: https://api.example.com/items
Defensive patterns

Strategy: type-guard

Validate before calling

import yaml

def is_yaml_mapping(q: str) -> bool:
    parsed = yaml.safe_load(q)
    return isinstance(parsed, dict)

Type guard

def is_valid_json_ds_query(q: str) -> bool:
    try:
        parsed = yaml.safe_load(q)
    except yaml.YAMLError:
        return False
    return isinstance(parsed, dict) and "url" in parsed

Try / catch

try:
    runner.run_query(q, user)
except QueryParseError as e:
    if "YAML object" in str(e):
        show_hint("Start the query with 'url: <full URL>' at top level")

Prevention

When it happens

Trigger: Query text like 'https://api.example.com' (YAML scalar) or '- url: ...' (YAML list of mappings) instead of 'url: ...' at top level.

Common situations: New users pasting a bare URL instead of YAML, pasting an array of request objects, indentation mistakes turning the mapping into something else.

Related errors


AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28). Data as JSON: /api/errors/5520caad8a7713aa. Report an issue: GitHub.