sipeed/picoclaw · error
no API key provided
Error message
no API key provided
What it means
BraveSearchProvider.Search refuses to run when its APIKeyPool is nil or has zero keys. The pool is built by NewAPIKeyPool(keys) from configured Brave API keys; in the standard WebTool wiring, providers without credentials are not registered at all, so hitting this usually means direct provider construction or a config race.
Source
Thrown at pkg/tools/integration/web.go:285
return nil
}
return lens
}
type BraveSearchProvider struct {
keyPool *APIKeyPool
proxy string
client *http.Client
}
func (p *BraveSearchProvider) Search(
ctx context.Context,
query string,
count int,
rangeCode string,
) (string, error) {
if p.keyPool == nil || len(p.keyPool.keys) == 0 {
return "", errors.New("no API key provided")
}
searchURL := fmt.Sprintf("https://api.search.brave.com/res/v1/web/search?q=%s&count=%d",
url.QueryEscape(query), count)
if freshness := mapBraveFreshness(rangeCode); freshness != "" {
searchURL += "&freshness=" + url.QueryEscape(freshness)
}
var lastErr error
iter := p.keyPool.NewIterator()
for {
apiKey, ok := iter.Next()
if !ok {
break
}
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)View on GitHub (pinned to 49183d7e8d)
Solutions
- Configure the Brave API key(s) for the web search provider in picoclaw config (or the env var your deployment reads them from) and restart
- Verify the key list actually reaches the provider: len(pool.Keys) > 0 before serving
- If no Brave key is available, switch the provider to one with credentials or to SearXNG (needs only a URL)
Example fix
// before
p := &integration.BraveSearchProvider{} // no keyPool
// after
pool := integration.NewAPIKeyPool([]string{os.Getenv("BRAVE_API_KEY")})
p := &integration.BraveSearchProvider{KeyPool: pool} Defensive patterns
Strategy: validation
Validate before calling
keys := []string{os.Getenv("BRAVE_API_KEY")}
keys = slices.DeleteFunc(keys, func(k string) bool { return strings.TrimSpace(k) == "" })
if len(keys) == 0 {
return errors.New("brave selected but no API key configured")
}
p := &integration.BraveSearchProvider{KeyPool: integration.NewAPIKeyPool(keys)} Try / catch
result, err := provider.Search(ctx, q, n, rangeCode)
if err != nil {
if err.Error() == "no API key provided" {
// config problem: disable brave or load keys, do not retry
}
return err
} Prevention
- Fail fast at startup when the selected provider has no keys instead of at first search
- Export provider keys in the actual service environment (systemd/docker), not just your shell
- Prefer SearXNG for keyless deployments
When it happens
Trigger: Calling Search on a BraveSearchProvider constructed with an empty key list (NewAPIKeyPool(nil) / NewAPIKeyPool([]string{})), i.e. brave is selected but no API key made it into the provider.
Common situations: Brave set as the web-search provider in picoclaw config without its API key(s); key env var not exported in the service unit; multiple keys configured as a single comma string instead of a list so parsing yields nothing.
Related errors
- no SearXNG URL provided
- credential: enc:// passphrase required
- credential: enc:// decryption failed (wrong passphrase or SS
- host cannot be empty
- host list contains an empty entry
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/6e3e47a39a5f575c.
Report an issue: GitHub.