{"record":{"id":"06328b926de2d25c","repo":"FoundationAgents/MetaGPT","slug":"got-error-from-serpapi-res-error","errorCode":null,"errorMessage":"Got error from SerpAPI: {res['error']}","messagePattern":"Got error from SerpAPI: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/tools/search_engine_serpapi.py","lineNumber":90,"sourceCode":"        _params = {\n            \"api_key\": self.api_key,\n            \"q\": query,\n        }\n        params = {**self.params, **_params}\n        return params\n\n    @staticmethod\n    def _process_response(res: dict, as_string: bool) -> str:\n        \"\"\"Process response from SerpAPI.\"\"\"\n        # logger.debug(res)\n        focus = [\"title\", \"snippet\", \"link\"]\n        get_focused = lambda x: {i: j for i, j in x.items() if i in focus}\n\n        if \"error\" in res.keys():\n            if res[\"error\"] == \"Google hasn't returned any results for this query.\":\n                toret = \"No good search result found\"\n            else:\n                raise ValueError(f\"Got error from SerpAPI: {res['error']}\")\n        elif \"answer_box\" in res.keys() and \"answer\" in res[\"answer_box\"].keys():\n            toret = res[\"answer_box\"][\"answer\"]\n        elif \"answer_box\" in res.keys() and \"snippet\" in res[\"answer_box\"].keys():\n            toret = res[\"answer_box\"][\"snippet\"]\n        elif \"answer_box\" in res.keys() and \"snippet_highlighted_words\" in res[\"answer_box\"].keys():\n            toret = res[\"answer_box\"][\"snippet_highlighted_words\"][0]\n        elif \"sports_results\" in res.keys() and \"game_spotlight\" in res[\"sports_results\"].keys():\n            toret = res[\"sports_results\"][\"game_spotlight\"]\n        elif \"knowledge_graph\" in res.keys() and \"description\" in res[\"knowledge_graph\"].keys():\n            toret = res[\"knowledge_graph\"][\"description\"]\n        elif \"snippet\" in res[\"organic_results\"][0].keys():\n            toret = res[\"organic_results\"][0][\"snippet\"]\n        else:\n            toret = \"No good search result found\"\n\n        toret_l = []\n        if \"answer_box\" in res.keys() and \"snippet\" in res[\"answer_box\"].keys():\n            toret_l += [get_focused(res[\"answer_box\"])]","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/tools/search_engine_serpapi.py#L72-L108","documentation":"ValueError from SerperAPIWrapper._process_response: the SerpAPI HTTP call succeeded but the JSON payload contains an 'error' key. The only tolerated error is the specific 'Google hasn't returned any results for this query.' string (mapped to 'No good search result found'); every other upstream error string is re-raised verbatim.","triggerScenarios":"Invalid or expired API key; exhausted plan credits; rate limiting; malformed query parameters — any SerpAPI response whose 'error' field differs from the no-results string.","commonSituations":"Key rotated but code/config still holds the old one; free tier quota hit during batch research runs; transient upstream errors surfacing mid-pipeline.","solutions":["Inspect the embedded error string: 'Invalid API key' -> update the key; quota/credit messages -> top up or wait","Wrap run/results in try/except ValueError and retry with backoff for transient upstream errors","Check account status at serpapi.com if errors persist with a valid key"],"exampleFix":"# before\nresults = await serpapi.run(query)\n# after\ntry:\n    results = await serpapi.run(query)\nexcept ValueError as e:\n    if \"Invalid API key\" in str(e):\n        raise  # credential problem: fix the key\n    await asyncio.sleep(5)  # transient upstream error: back off and retry\n    results = await serpapi.run(query)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"import asyncio\nfrom tenacity import retry, stop_after_attempt, wait_exponential\n@retry(stop=stop_after_attempt(3), wait=wait_exponential(min=2, max=30), retry_error_cb=lambda e: 'Invalid API key' not in str(e))\nasync def search(serpapi, query):\n    return await serpapi.run(query)","preventionTips":["Classify the embedded error string: credential errors are permanent, quota/transient ones are retryable","Monitor credit usage before batch runs","Alert on repeated upstream errors rather than swallowing them"],"tags":["search","serpapi","api-error","credentials","quota"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}