{"record":{"id":"2d9ea33b3a5d12c9","repo":"FoundationAgents/MetaGPT","slug":"to-use-serper-search-engine-make-sure-you-provide","errorCode":null,"errorMessage":"To use serper search engine, make sure you provide the `api_key` when constructing an object. You can obtain an API key from https://serper.dev/.","messagePattern":"To use serper search engine, make sure you provide the `api_key` when constructing an object\\. You can obtain an API key from https://serper\\.dev/\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/tools/search_engine_serper.py","lineNumber":33,"sourceCode":"\nclass SerperWrapper(BaseModel):\n    model_config = ConfigDict(arbitrary_types_allowed=True)\n\n    api_key: str\n    url: str = \"https://google.serper.dev/search\"\n    payload: dict = Field(default_factory=lambda: {\"page\": 1, \"num\": 10})\n    aiosession: Optional[aiohttp.ClientSession] = None\n    proxy: Optional[str] = None\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def validate_serper(cls, values: dict) -> dict:\n        if \"serper_api_key\" in values:\n            values.setdefault(\"api_key\", values[\"serper_api_key\"])\n            warnings.warn(\"`serper_api_key` is deprecated, use `api_key` instead\", DeprecationWarning, stacklevel=2)\n\n        if \"api_key\" not in values:\n            raise ValueError(\n                \"To use serper search engine, make sure you provide the `api_key` when constructing an object. You can obtain \"\n                \"an API key from https://serper.dev/.\"\n            )\n\n        return values\n\n    async def run(self, query: str, max_results: int = 8, as_string: bool = True, **kwargs: Any) -> str:\n        \"\"\"Run query through Serper and parse result async.\"\"\"\n        if isinstance(query, str):\n            return self._process_response((await self.results([query], max_results))[0], as_string=as_string)\n        else:\n            results = [self._process_response(res, as_string) for res in await self.results(query, max_results)]\n        return \"\\n\".join(results) if as_string else results\n\n    async def results(self, queries: list[str], max_results: int = 8) -> dict:\n        \"\"\"Use aiohttp to run query through Serper and return the results async.\"\"\"\n\n        payloads = self.get_payloads(queries, max_results)","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/tools/search_engine_serper.py#L15-L51","documentation":"ValueError from SerperWrapper's model_validator (mode='before'): constructor values contain neither api_key nor the deprecated serper_api_key alias. Serper.dev requires an API key, so instantiation fails fast before any HTTP call. The legacy alias is accepted with a DeprecationWarning.","triggerScenarios":"SerperWrapper() with no args; MetaGPT config selects the serper engine without an api_key; key expected from env var that isn't set in the runtime shell.","commonSituations":"Switching SearchEngine to serper without configuring SERPER_API_KEY; .env omitted from deployment; config migrated to new field names incompletely.","solutions":["Pass the key: SerperWrapper(api_key=os.environ['SERPER_API_KEY'])","Or set api_key under the search engine config in your MetaGPT yaml","Legacy serper_api_key field still works if present in old configs"],"exampleFix":"# before\nengine = SerperWrapper()  # ValueError\n# after\nengine = SerperWrapper(api_key=os.environ[\"SERPER_API_KEY\"])","handlingStrategy":"validation","validationCode":"import os\napi_key = os.environ.get(\"SERPER_API_KEY\")\nif not api_key:\n    raise SystemExit(\"set SERPER_API_KEY before constructing SerperWrapper\")","typeGuard":null,"tryCatchPattern":"try:\n    engine = SerperWrapper(api_key=k)\nexcept ValueError as e:\n    raise ConfigError(str(e))","preventionTips":["Preflight-check SERPER_API_KEY at startup","Migrate legacy serper_api_key config fields to api_key","Cache the constructed wrapper instead of rebuilding per request"],"tags":["search","serper","credentials","config","pydantic"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}