{"record":{"id":"15d98e42a932026d","repo":"getredash/redash","slug":"local-variable-result-should-be-of-type-dict","errorCode":null,"errorMessage":"local variable `result` should be of type `dict`.","messagePattern":"local variable `result` should be of type `dict`\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"redash/query_runner/python.py","lineNumber":321,"sourceCode":"    def _get_current_user(self):\n        user = getattr(self, \"_current_user\", None)\n        if user is None:\n            raise Exception(\"Python query helpers require a current user.\")\n        return user\n\n    def test_connection(self):\n        pass\n\n    def validate_result(self, result):\n        \"\"\"Validate the result after executing the query.\n\n        Parameters:\n        :result dict: The result dict.\n        \"\"\"\n        if not result:\n            raise Exception(\"local variable `result` should not be empty.\")\n        if not isinstance(result, dict):\n            raise Exception(\"local variable `result` should be of type `dict`.\")\n        if \"rows\" not in result:\n            raise Exception(\"Missing `rows` field in `result` dict.\")\n        if \"columns\" not in result:\n            raise Exception(\"Missing `columns` field in `result` dict.\")\n        if not isinstance(result[\"rows\"], list):\n            raise Exception(\"`rows` field should be of type `list`.\")\n        if not isinstance(result[\"columns\"], list):\n            raise Exception(\"`columns` field should be of type `list`.\")\n\n    def run_query(self, query, user):\n        self._current_user = user\n\n        try:\n            error = None\n\n            code = compile_restricted(query, \"<string>\", \"exec\")\n\n            builtins = safe_builtins.copy()","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/query_runner/python.py#L303-L339","documentation":"Second check in validate_result(): `result` must be a dict (the runner later reads result['rows'] / result['columns']). Scripts that set result to a pandas DataFrame, list of dicts, tuple, or JSON string fail here with the message \"local variable `result` should be of type `dict`.\"","triggerScenarios":"Ending a Python query with `result = df` (DataFrame), `result = df.to_json()`, or `result = rows_list` instead of a dict with 'rows'/'columns' keys.","commonSituations":"Authors assume the runner accepts a DataFrame like other notebook tools; or serialize with to_json()/dict(df) producing a non-standard structure.","solutions":["Use the built-in helper: result = dataframe_to_result({'columns': [], 'rows': []}, df) to convert a DataFrame","Otherwise build the dict manually: result = {'columns': [...], 'rows': df.to_dict('records')}"],"exampleFix":"# before\nresult = df  # DataFrame\n# after\nresult = dataframe_to_result({'columns': [], 'rows': []}, df)","handlingStrategy":"type-guard","validationCode":"assert isinstance(result, dict) and 'rows' in result and 'columns' in result, 'result must be a dict with rows/columns'","typeGuard":"def result_is_dict(r) -> bool:\n    return isinstance(r, dict)","tryCatchPattern":null,"preventionTips":["Never assign a DataFrame/list/JSON string to result","Use dataframe_to_result(result, df) to convert DataFrames","Keep result a plain dict: use dataframe_to_result / pandas_to_result helpers"],"tags":["redash","python-runner","result-validation","type-validation"],"backgroundTag":"query-result-schema-invalid","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}