getredash/redash · error · Exception

local variable `result` should be of type `dict`.

Error message

local variable `result` should be of type `dict`.

What it means

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`."

Source

Thrown at redash/query_runner/python.py:321

    def _get_current_user(self):
        user = getattr(self, "_current_user", None)
        if user is None:
            raise Exception("Python query helpers require a current user.")
        return user

    def test_connection(self):
        pass

    def validate_result(self, result):
        """Validate the result after executing the query.

        Parameters:
        :result dict: The result dict.
        """
        if not result:
            raise Exception("local variable `result` should not be empty.")
        if not isinstance(result, dict):
            raise Exception("local variable `result` should be of type `dict`.")
        if "rows" not in result:
            raise Exception("Missing `rows` field in `result` dict.")
        if "columns" not in result:
            raise Exception("Missing `columns` field in `result` dict.")
        if not isinstance(result["rows"], list):
            raise Exception("`rows` field should be of type `list`.")
        if not isinstance(result["columns"], list):
            raise Exception("`columns` field should be of type `list`.")

    def run_query(self, query, user):
        self._current_user = user

        try:
            error = None

            code = compile_restricted(query, "<string>", "exec")

            builtins = safe_builtins.copy()

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Use the built-in helper: result = dataframe_to_result({'columns': [], 'rows': []}, df) to convert a DataFrame
  2. Otherwise build the dict manually: result = {'columns': [...], 'rows': df.to_dict('records')}

Example fix

# before
result = df  # DataFrame
# after
result = dataframe_to_result({'columns': [], 'rows': []}, df)
Defensive patterns

Strategy: type-guard

Validate before calling

assert isinstance(result, dict) and 'rows' in result and 'columns' in result, 'result must be a dict with rows/columns'

Type guard

def result_is_dict(r) -> bool:
    return isinstance(r, dict)

Prevention

When it happens

Trigger: Ending a Python query with `result = df` (DataFrame), `result = df.to_json()`, or `result = rows_list` instead of a dict with 'rows'/'columns' keys.

Common situations: Authors assume the runner accepts a DataFrame like other notebook tools; or serialize with to_json()/dict(df) producing a non-standard structure.

Related errors


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