{"record":{"id":"5520caad8a7713aa","repo":"getredash/redash","slug":"query-should-be-a-yaml-object-describing-the-url-t","errorCode":null,"errorMessage":"Query should be a YAML object describing the URL to query.","messagePattern":"Query should be a YAML object describing the URL to query\\.","errorType":"validation","errorClass":"QueryParseError","httpStatus":null,"severity":"warning","filePath":"redash/query_runner/json_ds.py","lineNumber":170,"sourceCode":"        self.syntax = \"yaml\"\n\n    def test_connection(self):\n        pass\n\n    def run_query(self, query, user):\n        query = parse_query(query)\n\n        data, error = self._run_json_query(query)\n        if error is not None:\n            return None, error\n\n        if data:\n            return data, None\n        return None, \"Got empty response from '{}'.\".format(query[\"url\"])\n\n    def _run_json_query(self, query):\n        if not isinstance(query, dict):\n            raise QueryParseError(\"Query should be a YAML object describing the URL to query.\")\n\n        if \"url\" not in query:\n            raise QueryParseError(\"Query must include 'url' option.\")\n\n        method = query.get(\"method\", \"get\")\n        request_options = project(query, (\"params\", \"headers\", \"data\", \"auth\", \"json\", \"verify\"))\n\n        fields = query.get(\"fields\")\n        path = query.get(\"path\")\n\n        if \"pagination\" in query:\n            pagination = RequestPagination.from_config(self.configuration, query[\"pagination\"])\n        else:\n            pagination = None\n\n        if isinstance(request_options.get(\"auth\", None), list):\n            request_options[\"auth\"] = tuple(request_options[\"auth\"])\n        elif self.configuration.get(\"username\") or self.configuration.get(\"password\"):","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/query_runner/json_ds.py#L152-L188","documentation":"_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.').","triggerScenarios":"Query text like 'https://api.example.com' (YAML scalar) or '- url: ...' (YAML list of mappings) instead of 'url: ...' at top level.","commonSituations":"New users pasting a bare URL instead of YAML, pasting an array of request objects, indentation mistakes turning the mapping into something else.","solutions":["Rewrite as a top-level YAML mapping starting with 'url:', e.g. url: https://api.example.com/items","If a list was intended, run one query per item or restructure to a single mapping"],"exampleFix":"# before\nhttps://api.example.com/items\n# after\nurl: https://api.example.com/items","handlingStrategy":"type-guard","validationCode":"import yaml\n\ndef is_yaml_mapping(q: str) -> bool:\n    parsed = yaml.safe_load(q)\n    return isinstance(parsed, dict)","typeGuard":"def is_valid_json_ds_query(q: str) -> bool:\n    try:\n        parsed = yaml.safe_load(q)\n    except yaml.YAMLError:\n        return False\n    return isinstance(parsed, dict) and \"url\" in parsed","tryCatchPattern":"try:\n    runner.run_query(q, user)\nexcept QueryParseError as e:\n    if \"YAML object\" in str(e):\n        show_hint(\"Start the query with 'url: <full URL>' at top level\")","preventionTips":["Always start queries with a top-level url: key","Lint YAML client-side with yaml.safe_load before submission","Use block-style YAML to avoid scalar/list ambiguity"],"tags":["json-ds","yaml","query-validation"],"backgroundTag":"invalid-query-format","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}