zylon-ai/private-gpt · error · Exception
Brave Search API error ({status_code}): {error_message}
Error message
Brave Search API error ({status_code}): {error_message} What it means
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.
Source
Thrown at private_gpt/components/web/web_search/providers/brave.py:248
)
status_code = response.status
if status_code < 400:
return
error = response_data.get("error", "Unknown error")
error_message = self._extract_error_message(error)
if status_code == 429:
logger.debug(f"Brave Search API rate limit exceeded: {error_message}")
raise RateLimitExceeded(
f"Brave Search API rate limit exceeded: {error_message}"
)
elif status_code == 400:
raise ValueError(f"Brave Search API invalid token ({error_message})")
elif status_code >= 500:
raise Exception(f"Brave Search API server error: {error_message}")
else:
raise Exception(f"Brave Search API error ({status_code}): {error_message}")
def _build_request_params(
self,
query: str,
num_links: int,
offset: int,
result_filter: str,
safesearch: bool,
freshness: str | None,
spellcheck: bool,
language: str | None,
) -> dict[str, Any]:
params = {
"q": query.strip(),
"count": num_links,
"offset": offset,
"result_filter": result_filter,
"safesearch": "strict" if safesearch else "off",View on GitHub (pinned to 4a030776a3)
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.
Defensive patterns
Strategy: try-catch
Type guard
import re
def is_brave_api_error(exc: BaseException) -> bool:
return bool(re.search(r'Brave Search API error \(\d{3}\)', str(exc))) Try / catch
import re
try:
results = await provider.make_query(q, num_links)
except Exception as e:
m = re.search(r'Brave Search API error \((\d{3})\)', str(e))
if m and m.group(1) in ('401', '403'):
raise RuntimeError('Auth problem: check the Brave subscription token') from e
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Key revoked after plan cancellation; self-hosted proxy rewriting headers and dropping the token; API version drift after Brave changes its endpoint path.
Related errors
- Brave Search API quota exhausted (x-ratelimit-remaining=0)
- Brave Search API rate limit exceeded: {error_message}
- Invalid page token
- Scrape script failed (exit_code={result.exit_code}): {error}
- Brave Search API key is not configured
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/d40e22c52c68ea90.
Report an issue: GitHub.