vxcontrol/pentagi · error

failed to call llm after %d retries: %w

Error message

failed to call llm after %d retries: %w

What it means

callWithSetupRetries calls prv.Call up to maxRetriesToCallSimpleChain times with backoff; when every attempt fails it wraps the last error in this message. The wrapped error holds the final underlying failure (auth, network, rate limit, content filter, etc.).

Source

Thrown at backend/pkg/providers/providers.go:1090

// assistant bootstrap (docker image, language, and title selection) with the
// same short retry-with-backoff already used for the agent execution loop
// (see performSimpleChain/callWithRetries), so one transient error from the
// LLM gateway (e.g. a bad gateway from a litellm proxy) does not fail flow or
// assistant creation outright.
func callWithSetupRetries(
	ctx context.Context,
	prv provider.Provider,
	opt pconfig.ProviderOptionsType,
	prompt string,
) (string, error) {
	var (
		result string
		err    error
	)

	for idx := 0; idx <= maxRetriesToCallSimpleChain; idx++ {
		if idx == maxRetriesToCallSimpleChain {
			return "", fmt.Errorf("failed to call llm after %d retries: %w", idx, err)
		}

		result, err = prv.Call(ctx, opt, prompt)
		if err == nil {
			return result, nil
		}

		if errors.Is(err, context.Canceled) {
			return "", err
		}

		select {
		case <-ctx.Done():
			return "", ctx.Err()
		case <-time.After(delayBetweenRetries):
		}
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped final error for the HTTP status or cause of the last Call.
  2. Verify credentials and account quota with the provider directly.
  3. Check network egress/proxy from the backend container to the provider endpoint.
  4. If deterministic (e.g. context length exceeded), fix the prompt/model config — retrying won't help.
  5. Increase resilience: retry only applies to transient errors; consider a fallback provider.

Example fix

// before: all attempts 401
pc.cfg.OpenAIAPIKey = "" // stale key
// after
pc.cfg.OpenAIAPIKey = os.Getenv("OPENAI_API_KEY") // valid key; calls succeed on first attempt
Defensive patterns

Strategy: retry

Validate before calling

if prv == nil || ctx.Err() != nil {
    return "", fmt.Errorf("provider not ready or context canceled before call")
}

Type guard

null

Try / catch

result, err := callWithSetupRetries(ctx, prv, opt, prompt)
if err != nil {
    var final error
    if errors.As(err, &final) {
        log.Printf("LLM call failed permanently: %v", final) // inspect last Call error
    }
    if ctx.Err() != nil {
        return ctx.Err()
    }
    return err
}

Prevention

When it happens

Trigger: NewFlowProvider / NewAssistantProvider LLM calls where all retries fail: persistent 401/403, exhausted quota, unreachable endpoint, context deadline exceeded, or a deterministic model error that no retry can fix.

Common situations: Invalid API key; account out of credits; provider outage; prompt consistently rejected (too long, content policy); network egress blocked in a containerized deployment.

Related errors


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