{"record":{"id":"104c05fac284ce24","repo":"getredash/redash","slug":"query-must-include-url-option","errorCode":null,"errorMessage":"Query must include 'url' option.","messagePattern":"Query must include 'url' option\\.","errorType":"validation","errorClass":"QueryParseError","httpStatus":null,"severity":"warning","filePath":"redash/query_runner/json_ds.py","lineNumber":173,"sourceCode":"        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\"):\n            request_options[\"auth\"] = (self.configuration.get(\"username\"), self.configuration.get(\"password\"))\n\n        if method not in (\"get\", \"post\"):","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/query_runner/json_ds.py#L155-L191","documentation":"After confirming the query is a dict, _run_json_query checks for the mandatory 'url' key; without it there is nothing to fetch, so it raises QueryParseError(\"Query must include 'url' option.\").","triggerScenarios":"A YAML mapping that sets only method/params/pagination/fields but omits url, typically due to a typo (Url:, uri:, endpoint:) or an over-edited example.","commonSituations":"Copying template queries and deleting the url line, renaming keys, indentation placing url under another key so it's not top-level.","solutions":["Add a top-level url: <full URL> key","Check spelling/case and that url is at column 0 (not nested under another key)"],"exampleFix":"# before\nmethod: post\nparams:\n  q: redash\n# after\nurl: https://api.example.com/search\nmethod: post\nparams:\n  q: redash","handlingStrategy":"validation","validationCode":"import yaml\n\ndef has_url_key(q: str) -> bool:\n    parsed = yaml.safe_load(q)\n    return isinstance(parsed, dict) and \"url\" in parsed","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":null,"preventionTips":["Include url: as a top-level key in every JSON URL query","Check for typos like uri/endpoint/Url","Validate the parsed mapping before running"],"tags":["json-ds","yaml","missing-key"],"backgroundTag":"missing-required-parameter","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}