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

  1. Set the API key for the provider in picoclaw config (or its env var) and retry the model-listing command.
  2. Confirm the key value has no surrounding whitespace or quotes and is not still a placeholder.
  3. Verify which config file and profile picoclaw loaded — an empty key usually means the wrong profile or file was picked up.
  4. 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

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


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/1be867fc8f706051. Report an issue: GitHub.