{"record":{"id":"6cece0e3f2470528","repo":"searxng/searxng","slug":"invalid-response-6cece0","errorCode":null,"errorMessage":"Invalid response","messagePattern":"Invalid response","errorType":"exception","errorClass":"SearxEngineAPIException","httpStatus":null,"severity":"error","filePath":"searx/engines/chinaso.py","lineNumber":117,"sourceCode":"    params[\"url\"] = f\"{base_url}/v5/general/v1/web/search?{urlencode(query_params)}\"\n    cookie = {\n        \"uid\": base64.b64encode(secrets.token_bytes(16)).decode(\"utf-8\"),\n    }\n    params[\"cookies\"] = cookie\n\n    return params\n\n\ndef response(resp):\n    try:\n        data = resp.json()\n    except Exception as e:\n        raise SearxEngineAPIException(f\"Invalid response: {e}\") from e\n\n    # Upstream returns {'status': 0, 'msg': 'empty result', 'data': {}} when there\n    # are no results; this is a valid empty result rather than an API error.\n    if not isinstance(data, dict) or \"data\" not in data:\n        raise SearxEngineAPIException(\"Invalid response\")\n    if not data[\"data\"]:\n        return []\n\n    results = []\n    if not data.get(\"data\", {}).get(\"data\"):\n        raise SearxEngineAPIException(\"Invalid response\")\n\n    for entry in data[\"data\"][\"data\"]:\n        published_date = None\n        if entry.get(\"timestamp\"):\n            try:\n                published_date = datetime.fromtimestamp(int(entry[\"timestamp\"]))\n            except (ValueError, TypeError):\n                pass\n\n        results.append(\n            {\n                'title': html_to_text(entry[\"title\"]),","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/searxng/searxng/blob/9fea41204fdfa7a5cfa15b0ebd12904c520478ce/searx/engines/chinaso.py#L99-L135","documentation":"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').","triggerScenarios":"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.","commonSituations":"API error envelope changed; query parameters the engine sends are no longer accepted; IP soft-banned returning {'msg': 'forbidden'} style responses.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"data = resp.json()\nif not isinstance(data, dict) or 'data' not in data:\n    msg = data.get('msg') if isinstance(data, dict) else data\n    logger.warning('chinaso error envelope: %s', msg)\n    return []","typeGuard":"def is_chinaso_results_payload(data) -> bool:\n    return (\n        isinstance(data, dict)\n        and isinstance(data.get('data'), dict)\n        and isinstance(data['data'].get('data'), list)\n    )","tryCatchPattern":"try:\n    ...\nexcept SearxEngineAPIException as e:\n    if str(e) == 'Invalid response':\n        # shape drift, inspect raw body\n        ...","preventionTips":["Pin tests against recorded upstream fixtures to catch contract drift early","Log full envelopes on shape errors","Prefer engines with documented stable APIs"],"tags":["searxng","chinaso","response-shape","api-contract"],"backgroundTag":"schema-validation-failed","analyzedSha":"9fea41204fdfa7a5cfa15b0ebd12904c520478ce","analyzedAt":"2026-08-27T06:40:00.395Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}