Tencent/WeKnora · error

API key is required for Exa provider

Error message

API key is required for Exa provider

What it means

NewExaProvider validates that the tenant-supplied WebSearchProviderParameters contain a non-empty API key; if the trimmed key is empty it refuses to construct the provider. This is an intentional configuration guard so misconfigured tenants fail fast at construction rather than at request time with a 401.

Source

Thrown at internal/infrastructure/web_search/exa.go:41

	defaultExaResults   = 5
	maxExaResults       = 100
	maxExaResponseBytes = 2 << 20
	maxExaContentRunes  = 12000
)

// ExaProvider implements web search using Exa's official Search API.
type ExaProvider struct {
	client      *http.Client
	baseURL     string
	apiKey      string
	includeText bool
}

// NewExaProvider creates an Exa provider from tenant-specific parameters.
func NewExaProvider(params types.WebSearchProviderParameters) (interfaces.WebSearchProvider, error) {
	apiKey := strings.TrimSpace(params.APIKey)
	if apiKey == "" {
		return nil, fmt.Errorf("API key is required for Exa provider")
	}
	client, err := NewSearchHTTPClient(defaultExaTimeout, params.ProxyURL)
	if err != nil {
		return nil, err
	}
	return &ExaProvider{
		client:      client,
		baseURL:     defaultExaSearchURL,
		apiKey:      apiKey,
		includeText: parseExaBool(params.ExtraConfig, "include_text"),
	}, nil
}

// Name returns the provider type identifier.
func (p *ExaProvider) Name() string { return "exa" }

// Search performs a web search through Exa's official Search API.
func (p *ExaProvider) Search(

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set the Exa API key in the tenant web-search provider parameters
  2. Ensure the backing environment variable/secret (e.g. EXA_API_KEY) is present in the deployment
  3. Trim and re-save the config if the key was stored with stray whitespace
  4. Fall back to or select a different configured search provider if no Exa key is available

Example fix

// before
provider, err := NewExaProvider(types.WebSearchProviderParameters{})
// after
if os.Getenv("EXA_API_KEY") == "" {
    log.Fatal("EXA_API_KEY not set")
}
provider, err := NewExaProvider(types.WebSearchProviderParameters{APIKey: os.Getenv("EXA_API_KEY")})
Defensive patterns

Strategy: validation

Validate before calling

func validateExaParams(p types.WebSearchProviderParameters) error {
    if strings.TrimSpace(p.APIKey) == "" {
        return errors.New("API key is required for Exa provider")
    }
    return nil
}

Try / catch

provider, err := NewExaProvider(params)
if err != nil {
    if strings.Contains(err.Error(), "API key is required") {
        return configureFallbackProvider() // e.g. DuckDuckGo/Tavily
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewExaProvider with params.APIKey empty or whitespace-only — e.g. the tenant web-search config was saved without a key, or the env var backing it was unset.

Common situations: Missing EXA_API_KEY in deployment env, config migration dropped the apiKey field, key stored with only whitespace, wiring the Exa provider while only a Tavily/DuckDuckGo key exists.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/ab4d09c017d7a595. Report an issue: GitHub.