{"record":{"id":"3736f704959ee2af","repo":"nexu-io/open-design","slug":"serper-api-key-is-required-when-web-backend-serpe","errorCode":null,"errorMessage":"SERPER_API_KEY is required when web_backend='serper'","messagePattern":"SERPER_API_KEY is required when web_backend='serper'","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"design-templates/last30days/scripts/lib/grounding.py","lineNumber":221,"sourceCode":"            backend = \"serper\"\n        elif config.get(\"PARALLEL_API_KEY\"):\n            backend = \"parallel\"\n        else:\n            return [], {}\n    if backend == \"brave\":\n        key = config.get(\"BRAVE_API_KEY\")\n        if not key:\n            raise RuntimeError(\"BRAVE_API_KEY is required when web_backend='brave'\")\n        return brave_search(query, date_range, key)\n    if backend == \"exa\":\n        key = config.get(\"EXA_API_KEY\")\n        if not key:\n            raise RuntimeError(\"EXA_API_KEY is required when web_backend='exa'\")\n        return exa_search(query, date_range, key)\n    if backend == \"serper\":\n        key = config.get(\"SERPER_API_KEY\")\n        if not key:\n            raise RuntimeError(\"SERPER_API_KEY is required when web_backend='serper'\")\n        return serper_search(query, date_range, key)\n    if backend == \"parallel\":\n        key = config.get(\"PARALLEL_API_KEY\")\n        if not key:\n            raise RuntimeError(\"PARALLEL_API_KEY is required when web_backend='parallel'\")\n        return parallel_search(query, date_range, key)\n    if backend != \"none\":\n        raise ValueError(f\"Unsupported web backend: {backend!r}\")\n    return [], {}\n\n\n# ---------------------------------------------------------------------------\n# Helpers\n# ---------------------------------------------------------------------------\n\ndef _normalize_date(value: object) -> str | None:\n    if value is None:\n        return None","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/design-templates/last30days/scripts/lib/grounding.py#L203-L239","documentation":"Same dispatcher guard for the 'serper' branch: backend is 'serper' but config.get('SERPER_API_KEY') is empty/missing. RuntimeError(\"SERPER_API_KEY is required when web_backend='serper'\"). As with the sibling checks, auto-mode would not pick serper without the key, so this normally reflects an explicit `--web-backend serper`.","triggerScenarios":"`--web-backend serper` with SERPER_API_KEY unset/empty in config.","commonSituations":"Forcing serper without the key; secret not wired into CI; typo in the env var name.","solutions":["Export SERPER_API_KEY.","Use `--web-backend auto`, another backend you have a key for, or `--web-backend none`."],"exampleFix":"# before\npython3.12 last30days.py --topic x --web-backend serper   # SERPER_API_KEY unset\n# after\nexport SERPER_API_KEY=...\npython3.12 last30days.py --topic x --web-backend serper","handlingStrategy":"validation","validationCode":"if web_backend == 'serper' and not config.get('SERPER_API_KEY'):\n    raise RuntimeError(\"SERPER_API_KEY is required when web_backend='serper'\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer `--web-backend auto`.","Verify the secret is exported in the shell that launches the script."],"tags":["config","api-key","python","web-search","grounding"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}