getredash/redash · error · Exception
Invalid JSON response from D1: {str(e)}
Error message
Invalid JSON response from D1: {str(e)} What it means
D1 runner's _query catches json.JSONDecodeError when the Cloudflare API response body isn't valid JSON and re-raises with the parse detail. The HTTP call succeeded but the body couldn't be parsed.
Source
Thrown at redash/query_runner/d1.py:87
"Content-Type": "application/json",
}
body = {"sql": sql, "params": params or []}
try:
resp = session.post(self.configuration.get("cf_url"), headers=headers, data=json.dumps(body), timeout=30)
resp.raise_for_status()
data = resp.json()
# Expected: { "result": [ { "results": [...] } ] }
results = data.get("result", [])
if not results:
return []
return results[0].get("results", [])
except session.exceptions.RequestException as e:
raise Exception(f"Failed to connect to Cloudflare D1: {str(e)}")
except json.JSONDecodeError as e:
raise Exception(f"Invalid JSON response from D1: {str(e)}")
except KeyError as e:
raise Exception(f"Unexpected response format from D1: {str(e)}")
def run_query(self, query, user):
try:
rows = self._query(query)
if not rows:
return {"columns": [], "rows": []}, None
# Infer columns from first row
first_row = rows[0]
columns = []
for k, v in first_row.items():
# Get the Python type name and map it to Redash type
python_type = type(v).__name__
redash_type = TYPES_MAP.get(python_type, TYPE_STRING)
# Special handling for strings that look like datetimesView on GitHub (pinned to ca79fe988d)
Solutions
- Reproduce the request with curl and inspect the raw body
- Fix proxy/WAF rules that rewrite responses from api.cloudflare.com
- Confirm the request URL is the official API endpoint
- Retry during a Cloudflare incident if the body is an error page
Example fix
# before BASE_URL = "https://api.cloudflare.com" # after BASE_URL = "https://api.cloudflare.com/client/v4"
Defensive patterns
Strategy: try-catch
Validate before calling
import requests
r = requests.post(url, headers=h, json=body, timeout=10)
r.raise_for_status()
assert r.headers.get('content-type', '').startswith('application/json'), 'proxy is mangling responses' Try / catch
try:
rows = d1_runner._query(q)
except Exception as e:
if 'Invalid JSON response' in str(e):
inspect_raw_body_with_curl(); flag_proxy_config() Prevention
- Exclude API domains from TLS-intercepting proxies
- Alert on content-type mismatches from Cloudflare responses
- Retry during Cloudflare incident windows
When it happens
Trigger: The D1 endpoint returning HTML (a proxy/CDN error page), an empty body, or truncated output that json.loads can't parse.
Common situations: Corporate proxy returning an HTML block page, Cloudflare serving a non-JSON error page during incidents, or a base URL pointing at a non-API host.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to connect to Cloudflare D1: {str(e)}
- Unexpected response format from D1: {str(e)}
- Failed to get schema: {str(e)}
- Redash failed to parse the results it got from Elasticsearch
- Invalid JWT token
AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28).
Data as JSON: /api/errors/113ee63aaba1f1c2.
Report an issue: GitHub.