{"record":{"id":"d40e22c52c68ea90","repo":"zylon-ai/private-gpt","slug":"brave-search-api-error-status-code-error-mes","errorCode":null,"errorMessage":"Brave Search API error ({status_code}): {error_message}","messagePattern":"Brave Search API error \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"private_gpt/components/web/web_search/providers/brave.py","lineNumber":248,"sourceCode":"            )\n\n        status_code = response.status\n        if status_code < 400:\n            return\n\n        error = response_data.get(\"error\", \"Unknown error\")\n        error_message = self._extract_error_message(error)\n        if status_code == 429:\n            logger.debug(f\"Brave Search API rate limit exceeded: {error_message}\")\n            raise RateLimitExceeded(\n                f\"Brave Search API rate limit exceeded: {error_message}\"\n            )\n        elif status_code == 400:\n            raise ValueError(f\"Brave Search API invalid token ({error_message})\")\n        elif status_code >= 500:\n            raise Exception(f\"Brave Search API server error: {error_message}\")\n        else:\n            raise Exception(f\"Brave Search API error ({status_code}): {error_message}\")\n\n    def _build_request_params(\n        self,\n        query: str,\n        num_links: int,\n        offset: int,\n        result_filter: str,\n        safesearch: bool,\n        freshness: str | None,\n        spellcheck: bool,\n        language: str | None,\n    ) -> dict[str, Any]:\n        params = {\n            \"q\": query.strip(),\n            \"count\": num_links,\n            \"offset\": offset,\n            \"result_filter\": result_filter,\n            \"safesearch\": \"strict\" if safesearch else \"off\",","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/web/web_search/providers/brave.py#L230-L266","documentation":"Catch-all Exception for Brave responses with any other 4xx status (401/403/404 etc. — everything not 400/429/5xx). The message includes the status code and the error detail from the response body, so the specific cause can be read directly.","triggerScenarios":"401/403 from a missing/invalid X-Subscription-Token (key deleted or wrong header); 404 from pointing at a wrong base URL or API version; 422 from parameters Brave rejects in a way the client did not pre-validate.","commonSituations":"Key revoked after plan cancellation; self-hosted proxy rewriting headers and dropping the token; API version drift after Brave changes its endpoint path.","solutions":["Read the embedded status code: 401/403 → fix the API key/permissions; 404 → verify the endpoint/base URL; 422 → fix the offending parameter.","Regenerate the key if it was revoked and update settings.","Confirm no intermediary (proxy, service mesh) strips the X-Subscription-Token header.","Pin the API version used by the provider and check Brave's changelog after upgrading private-gpt."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import re\n\ndef is_brave_api_error(exc: BaseException) -> bool:\n    return bool(re.search(r'Brave Search API error \\(\\d{3}\\)', str(exc)))","tryCatchPattern":"import re\n\ntry:\n    results = await provider.make_query(q, num_links)\nexcept Exception as e:\n    m = re.search(r'Brave Search API error \\((\\d{3})\\)', str(e))\n    if m and m.group(1) in ('401', '403'):\n        raise RuntimeError('Auth problem: check the Brave subscription token') from e\n    raise","preventionTips":["Log the embedded status code; it distinguishes auth (401/403), endpoint (404) and param (422) issues.","Keep the base URL/API version in one place so migrations are deliberate.","Check header-stripping intermediaries when tokens silently stop working."],"tags":["brave","http-4xx","api","diagnostics"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}