sipeed/picoclaw · error
api key is required
Error message
api key is required
What it means
fetchOpenAIModels refuses to run without credentials: before any HTTP traffic it requires a non-blank API key because it sends that key as a Bearer Authorization header to the provider's /models endpoint. The guard is strings.TrimSpace(apiKey) == "", so a key of only spaces fails the same as an empty string.
Source
Thrown at cmd/picoclaw/internal/model/online.go:29
type modelEntry struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
}
type modelsAPIResponse struct {
Data []modelEntry `json:"data"`
}
// fetchOpenAIModels GETs <baseURL>/models with Bearer auth and accepts both the
// {data:[…]} envelope and a bare array shape used by various OpenAI-compatible servers.
func fetchOpenAIModels(baseURL, apiKey string) ([]modelEntry, error) {
if strings.TrimSpace(baseURL) == "" {
return nil, fmt.Errorf("api base is required")
}
if strings.TrimSpace(apiKey) == "" {
return nil, fmt.Errorf("api key is required")
}
url := strings.TrimRight(baseURL, "/") + "/models"
client := &http.Client{Timeout: 15 * time.Second}
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("build request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {View on GitHub (pinned to 49183d7e8d)
Solutions
- Set the API key for the provider in picoclaw config (or its env var) and retry the model-listing command.
- Confirm the key value has no surrounding whitespace or quotes and is not still a placeholder.
- Verify which config file and profile picoclaw loaded — an empty key usually means the wrong profile or file was picked up.
- If the server genuinely needs no auth, note the check is unconditional: supply any non-empty token or use a different code path.
Example fix
// before
fetchOpenAIModels("https://api.example.com/v1", "")
// after
fetchOpenAIModels("https://api.example.com/v1", os.Getenv("EXAMPLE_API_KEY")) Defensive patterns
Strategy: validation
Validate before calling
apiKey = strings.TrimSpace(apiKey)
if apiKey == "" {
return fmt.Errorf("api key is required")
}
entries, err := fetchOpenAIModels(baseURL, apiKey) Type guard
func hasAPIKey(key string) bool {
return strings.TrimSpace(key) != ""
} Prevention
- Fail fast on empty credentials at the config-loading layer so commands never start with a blank key.
- Log which config file and profile supplied the key when model listing runs.
- Add a config lint check that reports providers with an empty api key.
When it happens
Trigger: Invoking picoclaw's online model listing (fetchOpenAIModels at cmd/picoclaw/internal/model/online.go:29) with apiKey unset, "", or " ". The function fails immediately, before the GET to <baseURL>/models is built.
Common situations: Missing api key in the provider section of picoclaw's config, the key exported under a different env var name, the active profile not carrying the key, or a placeholder like <YOUR_KEY> that trims to nothing after template substitution.
Related errors
- invalid WeCom QR generate URL: %w
- invalid WeCom QR query URL: %w
- invalid WeCom QR page URL: %w
- build request: %w
- tool discovery is enabled but neither 'use_bm25' nor 'use_re
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/1be867fc8f706051.
Report an issue: GitHub.