getredash/redash · error · Exception

Couldn't find path {} in response.

Error message

Couldn't find path {} in response.

What it means

After fetching JSON, _apply_path_search walks the configured path components into the response dict; if a component key is absent and no default was provided, it raises 'Couldn't find path {} in response.' naming the full missing path.

Source

Thrown at redash/query_runner/json_ds.py:77

def add_column(columns, column_name, column_type):
    if _get_column_by_name(columns, column_name) is None:
        columns.append({"name": column_name, "friendly_name": column_name, "type": column_type})


def _apply_path_search(response, path, default=None):
    if path is None:
        return response

    path_parts = path.split(".")
    path_parts.reverse()
    while len(path_parts) > 0:
        current_path = path_parts.pop()
        if current_path in response:
            response = response[current_path]
        elif default is not None:
            return default
        else:
            raise Exception("Couldn't find path {} in response.".format(path))

    return response


def _normalize_json(data, path):
    if not data:
        return None
    data = _apply_path_search(data, path)

    if isinstance(data, dict):
        data = [data]

    return data


def _sort_columns_with_fields(columns, fields):
    if fields:
        columns = compact([_get_column_by_name(columns, field) for field in fields])

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Run the query without 'path' (or with a shallow path) and inspect the actual response structure in Redash's raw result
  2. Correct path keys to match the real envelope, e.g. path: data.items
  3. Add a 'default' for optional paths so missing keys fall back instead of raising
  4. If the API errors intermittently, use the JSON in a check or wrapper that validates status before querying

Example fix

# before
path: results.items
# after
path: data.items
Defensive patterns

Strategy: validation

Validate before calling

def path_exists(obj, path: str) -> bool:
    cur = obj
    for part in path.split("."):
        if isinstance(cur, dict) and part in cur:
            cur = cur[part]
        else:
            return False
    return True

# usage: fetch once, check path_exists(sample_response, configured_path) before querying

Try / catch

try:
    result = runner.run_query(q, user)
except Exception as e:
    if "Couldn't find path" in str(e):
        run_without_path_to_inspect_envelope_then_fix_path()

Prevention

When it happens

Trigger: Query includes path: a.b.c but the API response lacks one of those keys — e.g. pagination or an error payload changed the envelope ({'data': ...} vs direct list), or a typo in the path.

Common situations: API version change altering response envelope, endpoint returning an error object on failure, misspelled path keys, differing shapes between first and paginated pages.

Related errors


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