vxcontrol/pentagi · critical · Fatal
API key is wrong
Error message
API key is wrong
What it means
Thrown in tavily.parseHTTPResponse when Tavily answers HTTP 401 Unauthorized, mapped to "API key is wrong". Tavily authenticates via the api_key field of the JSON body (tavilyRequest.ApiKey), so this means the key sent is missing at the API level, revoked, expired, or malformed. Classified Fatal — retrying with the same credentials always fails.
Source
Thrown at backend/pkg/tools/searchers/tavily.go:152
return "", Retryable(fmt.Errorf("failed to do request: %v", err), 0)
}
defer resp.Body.Close()
return t.parseHTTPResponse(ctx, resp)
}
func (t *tavily) parseHTTPResponse(ctx context.Context, resp *http.Response) (string, error) {
switch resp.StatusCode {
case http.StatusOK:
var respBody tavilySearchResult
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
return "", Fatal(fmt.Errorf("failed to decode response body: %v", err))
}
return t.buildTavilyResult(ctx, &respBody), nil
case http.StatusBadRequest:
return "", Fatal(fmt.Errorf("request is invalid"))
case http.StatusUnauthorized:
return "", Fatal(fmt.Errorf("API key is wrong"))
case http.StatusForbidden:
return "", Fatal(fmt.Errorf("the endpoint requested is hidden for administrators only"))
case http.StatusNotFound:
return "", Fatal(fmt.Errorf("the specified endpoint could not be found"))
case http.StatusMethodNotAllowed:
return "", Fatal(fmt.Errorf("there need to try to access an endpoint with an invalid method"))
case http.StatusTooManyRequests:
return "", Retryable(fmt.Errorf("there are requesting too many results"), 0)
case http.StatusInternalServerError:
return "", Retryable(fmt.Errorf("there had a problem with our server. try again later"), 0)
case http.StatusBadGateway:
return "", Retryable(fmt.Errorf("there was a problem with the server. Please try again later"), 0)
case http.StatusServiceUnavailable:
return "", Retryable(fmt.Errorf("there are temporarily offline for maintenance. please try again later"), 0)
case http.StatusGatewayTimeout:
return "", Retryable(fmt.Errorf("there are temporarily offline for maintenance. please try again later"), 0)
default:
return "", Fatal(fmt.Errorf("unexpected status code: %d", resp.StatusCode))View on GitHub (pinned to ea665308ba)
Solutions
- Verify TAVILY_API_KEY in the container env (docker compose exec backend env | grep TAVILY) matches the current key from the Tavily dashboard — restart the container after .env changes.
- Re-copy the key without surrounding quotes, spaces, or newline characters.
- Regenerate the key in the Tavily dashboard if it was revoked, then update .env and restart.
- Confirm the key with a minimal curl: curl -s -X POST api.tavily.com/search -d '{"api_key":"tvly-...","query":"test"}' and check for 200.
- Check Tavily account status — suspended or over-quota accounts can also reject authentication.
Example fix
// before (.env) TAVILY_API_KEY="tvly-abc123 " // quotes + trailing space -> 401 // after (.env) TAVILY_API_KEY=tvly-abc123
Defensive patterns
Strategy: validation
Validate before calling
key := strings.TrimSpace(cfg.TavilyAPIKey)
if key == "" || !strings.HasPrefix(key, "tvly-") {
return "", ErrNotConfigured // don't even attempt the call
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "API key is wrong") {
// fatal config problem: alert an operator, do not retry
logger.Error("TAVILY_API_KEY rejected by api.tavily.com")
}
return err
} Prevention
- Set TAVILY_API_KEY without quotes/whitespace in .env and restart containers after rotation.
- Validate the key once at startup with a cheap curl or status call, not on the first user query.
- Track key expiry/rotation in the Tavily dashboard calendar.
- Keep the key only in .env/secret manager; grep for stray 'Bearer ' prefixes when pasting.
When it happens
Trigger: POST to api.tavily.com/search with tavilyRequest.ApiKey set to an empty (shouldn't happen — IsAvailable guards), stale, mistyped, or revoked key in cfg.TavilyAPIKey, producing a 401 from Tavily.
Common situations: TAVILY_API_KEY env var copied with quotes/whitespace/trailing newline from .env; key regenerated in the Tavily dashboard after the free-tier reset; .env not remounted into the running container after a key rotation; extra characters like 'Bearer ' pasted into the key.
Related errors
- cookie claim invalid
- session expired
- user hash mismatch - session invalid for this installation
- user has been deleted
- user has been blocked
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/2e5bc5feef9877a1.
Report an issue: GitHub.