{"record":{"id":"0d39dfefa7cf3719","repo":"getredash/redash","slug":"you-do-not-have-access-to-query-id","errorCode":null,"errorMessage":"You do not have access to query id {}.","messagePattern":"You do not have access to query id (.+?)\\.","errorType":"exception","errorClass":"PermissionError","httpStatus":403,"severity":"error","filePath":"redash/query_runner/query_results.py","lineNumber":54,"sourceCode":"    queries = re.findall(r\"(?:join|from)\\s+query_(\\d+)\", query, re.IGNORECASE)\n    return [int(q) for q in queries]\n\n\ndef extract_cached_query_ids(query):\n    queries = re.findall(r\"(?:join|from)\\s+cached_query_(\\d+)\", query, re.IGNORECASE)\n    return [int(q) for q in queries]\n\n\ndef _load_query(user, query_id):\n    query = models.Query.get_by_id(query_id)\n\n    if user.org_id != query.org_id:\n        raise PermissionError(\"Query id {} not found.\".format(query.id))\n\n    # TODO: this duplicates some of the logic we already have in the redash.handlers.query_results.\n    # We should merge it so it's consistent.\n    if not has_access(query.data_source, user, view_only):\n        raise PermissionError(\"You do not have access to query id {}.\".format(query.id))\n\n    return query\n\n\ndef replace_query_parameters(query_text, params):\n    qs = parse_qs(params)\n    for key, value in qs.items():\n        query_text = query_text.replace(\"{{{{{my_key}}}}}\".format(my_key=key), value[0])\n    return query_text\n\n\ndef get_query_results(user, query_id, bring_from_cache, params=None):\n    query = _load_query(user, query_id)\n    if bring_from_cache:\n        if query.latest_query_data_id is not None:\n            results = query.latest_query_data.data\n        else:\n            raise Exception(\"No cached result available for query {}.\".format(query.id))","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/query_runner/query_results.py#L36-L72","documentation":"Raised by _load_query (redash/query_runner/query_results.py:54) as a PermissionError when the query is in the user's organization but the user lacks view-only access to the query's data source. Access is evaluated with has_access(query.data_source, user, view_only), so group membership on the data source governs this path.","triggerScenarios":"Calling get_query_results / query_results runner where the user is not in any group that has (at least view-only) permissions on the query's data source; a user with a personal-only or restricted data source running a query that references it via query id.","commonSituations":"Query results loader ('load results of query X') pointed at a data source restricted to another group; newly provisioned users missing group membership; admins moving a query to a more restricted data source.","solutions":["Add the user (or their group) to the data source's groups with at least view-only access in Data Source settings","Ask the query owner to duplicate the query onto a data source the user can access","If you own the pipeline, catch PermissionError and surface an access-request message instead of a raw stack trace"],"exampleFix":"# before\nresults = get_query_results(user, query_id, bring_from_cache=True)\n# after\nfrom redash.permissions import has_access\nquery = models.Query.get_by_id(query_id)\nif not has_access(query.data_source, user, not user.is_admin() if False else view_only):\n    raise HTTPError(403)\nresults = get_query_results(user, query_id, bring_from_cache=True)","handlingStrategy":"try-catch","validationCode":"from redash import models\nfrom redash.permissions import has_access, view_only\nquery = models.Query.get_by_id(query_id)\nif query.org_id != user.org_id or not has_access(query.data_source, user, view_only):\n    return error_response(403, 'no access to query')","typeGuard":null,"tryCatchPattern":"try:\n    results = get_query_results(user, qid, bring_from_cache)\nexcept PermissionError as e:\n    return error_response(403, str(e))","preventionTips":["Grant the service/integration user at least view-only access on every data source it reads via loaders","Keep an access matrix of queries -> data sources when writing results-loader pipelines","Catch PermissionError separately from generic Exception to return proper 403s"],"tags":["redash","permissions","data-source","acl"],"backgroundTag":"permission-denied","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}