searxng/searxng · error · SearxEngineAPIException
Invalid response
Error message
Invalid response
What it means
After parsing JSON, the engine validates the payload shape: it must be a dict containing a 'data' key. Anything else (e.g. a JSON error object like {'status':1,'msg':'...'} or a list) raises SearxEngineAPIException('Invalid response').
Source
Thrown at searx/engines/chinaso.py:117
params["url"] = f"{base_url}/v5/general/v1/web/search?{urlencode(query_params)}"
cookie = {
"uid": base64.b64encode(secrets.token_bytes(16)).decode("utf-8"),
}
params["cookies"] = cookie
return params
def response(resp):
try:
data = resp.json()
except Exception as e:
raise SearxEngineAPIException(f"Invalid response: {e}") from e
# Upstream returns {'status': 0, 'msg': 'empty result', 'data': {}} when there
# are no results; this is a valid empty result rather than an API error.
if not isinstance(data, dict) or "data" not in data:
raise SearxEngineAPIException("Invalid response")
if not data["data"]:
return []
results = []
if not data.get("data", {}).get("data"):
raise SearxEngineAPIException("Invalid response")
for entry in data["data"]["data"]:
published_date = None
if entry.get("timestamp"):
try:
published_date = datetime.fromtimestamp(int(entry["timestamp"]))
except (ValueError, TypeError):
pass
results.append(
{
'title': html_to_text(entry["title"]),View on GitHub (pinned to 9fea41204f)
Solutions
- Log the full JSON body to see the actual upstream error message in the envelope
- Retry with backoff if it indicates rate limiting
- Update the engine to handle/recognize the new error envelope or disable it if the contract changed
- Verify request parameters (headers, cookies) still match what the API expects
Defensive patterns
Strategy: validation
Validate before calling
data = resp.json()
if not isinstance(data, dict) or 'data' not in data:
msg = data.get('msg') if isinstance(data, dict) else data
logger.warning('chinaso error envelope: %s', msg)
return [] Type guard
def is_chinaso_results_payload(data) -> bool:
return (
isinstance(data, dict)
and isinstance(data.get('data'), dict)
and isinstance(data['data'].get('data'), list)
) Try / catch
try:
...
except SearxEngineAPIException as e:
if str(e) == 'Invalid response':
# shape drift, inspect raw body
... Prevention
- Pin tests against recorded upstream fixtures to catch contract drift early
- Log full envelopes on shape errors
- Prefer engines with documented stable APIs
When it happens
Trigger: ChinaSo returns a JSON object without a 'data' key — typically an API-level error envelope (rate limit, invalid parameters, blocked client) rather than a search result payload.
Common situations: API error envelope changed; query parameters the engine sends are no longer accepted; IP soft-banned returning {'msg': 'forbidden'} style responses.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid response: {e}
- don't know how to extract messages from %s
- {obj_name} should be list or dict
- Botdetection's config is not yet initialized.
- schema of {cfg_file} is invalid!
AI-assisted analysis of searxng/searxng@9fea41204f (2026-08-27).
Data as JSON: /api/errors/6cece0e3f2470528.
Report an issue: GitHub.