vxcontrol/pentagi · warning · Retryable

there are requesting too many results

Error message

there are requesting too many results

What it means

Thrown in tavily.parseHTTPResponse when Tavily answers HTTP 429 Too Many Requests, mapped to "there are requesting too many results". The account hit its rate limit (requests per minute or monthly quota). Unlike the 4xx Fatal cases, this is wrapped as Retryable(err, 0), signaling the orchestrator to back off and retry or fall back to another engine.

Source

Thrown at backend/pkg/tools/searchers/tavily.go:160

	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))
	}
}

func (t *tavily) buildTavilyResult(ctx context.Context, result *tavilySearchResult) string {
	var writer strings.Builder
	writer.WriteString("# Answer\n\n")
	writer.WriteString(result.Answer)
	writer.WriteString("\n\n# Links\n\n")

View on GitHub (pinned to ea665308ba)

Solutions

  1. Let the built-in Retryable classification work: ensure the web_search orchestrator retries with backoff and check that a fallback engine is configured for sustained load.
  2. Upgrade the Tavily plan or increase rate limits to match your concurrency.
  3. Add client-side rate limiting/throttling (semaphore or token bucket) around Tavily calls to smooth bursts from parallel agents.
  4. Distribute searches across multiple configured engines (DuckDuckGo, Google, Searxng) instead of pinning everything to Tavily.
  5. Honor the Retry-After response header when backing off instead of retrying immediately.

Example fix

// before: unbounded parallel searches hit 429
for _, q := range queries { go t.search(ctx, q, 5) }
// after: throttle with a semaphore
sem := make(chan struct{}, 2) // stay under the rate limit
for _, q := range queries {
    sem <- struct{}{}
    go func(q string) { defer func() { <-sem }(); t.search(ctx, q, 5) }(q)
}
Defensive patterns

Strategy: retry

Validate before calling

// client-side budget check before issuing another request
if !limiter.Allow() { // e.g. golang.org/x/time/rate: rate.Limiter at the plan's QPS
    return "", Retryable(fmt.Errorf("local rate limit reached"), time.Second)
}

Try / catch

result, err := searcher.Handle(ctx, req)
if err != nil {
    var re *RetryableError
    if errors.As(err, &re) && strings.Contains(err.Error(), "too many results") {
        select {
        case <-time.After(backoff(retryN)): // exponential backoff, honor Retry-After if present
        case <-ctx.Done():
        }
        return retry(retryN + 1)
    }
    return err
}

Prevention

When it happens

Trigger: POST to api.tavily.com/search returns 429: too many concurrent agent flows issuing web_search calls, burst of queries from a single flow, or the free-tier monthly quota is exhausted.

Common situations: Multi-agent PentAGI runs firing many searches in parallel on a free Tavily plan (1 req/s style limits); shared API key used by multiple deployments; automated test suites hammering the API; end-of-month quota exhaustion on the free tier.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/3c5a31edce24f331. Report an issue: GitHub.