sipeed/picoclaw · error
fetch models: %w
Error message
fetch models: %w
What it means
Generic wrapper inside picoclaw model add around fetchOpenAIModels, which GETs <api-base>/models with Bearer auth and a 15s HTTP timeout. It fires for any listing failure: blank api base or key (reachable when the flags are passed empty, since values are trimmed), invalid URL, network error, non-200 status (body preview included), read failure, or a response body that is neither the {data:[...]} envelope nor a bare JSON array.
Source
Thrown at cmd/picoclaw/internal/model/add.go:106
alias string
modelType string
stdin io.Reader
stdout io.Writer
}
func runAdd(opt addOptions) error {
if opt.modelType != "" && opt.modelType != "openai-compatible" {
return fmt.Errorf("unsupported --type %q (only 'openai-compatible' is supported)", opt.modelType)
}
if opt.alias == "" {
opt.alias = defaultAliasName
}
selected := opt.modelID
if selected == "" {
entries, err := fetchOpenAIModels(opt.apiBase, opt.apiKey)
if err != nil {
return fmt.Errorf("fetch models: %w", err)
}
if len(entries) == 0 {
return fmt.Errorf("no models returned by %s", opt.apiBase)
}
selected, err = pickModel(opt.stdin, opt.stdout, entries)
if err != nil {
return err
}
}
return upsertModelDefault(opt.apiBase, opt.apiKey, opt.alias, selected, opt.stdout)
}
func pickModel(stdin io.Reader, stdout io.Writer, entries []modelEntry) (string, error) {
fmt.Fprintf(stdout, "\n%d model(s) available:\n", len(entries))
for i, m := range entries {
line := m.ID
if m.Name != "" && m.Name != m.ID {View on GitHub (pinned to 49183d7e8d)
Solutions
- Reproduce the exact call: curl -sS -H 'Authorization: Bearer <key>' <api-base>/models and inspect status and body
- Fix --api-base: include the scheme and match the provider-documented prefix (often ending in /v1)
- Verify the key is valid and allowed to list models
- Skip listing entirely with -m <model-id>, which stores the entry without contacting the server
- If the body is not JSON (HTML page), the base URL or proxy is wrong — fix it rather than the key
Example fix
# before $ picoclaw model add -b api.openai.com/v1 -k sk-... fetch models: request failed: Get "api.openai.com/v1/models": unsupported protocol scheme "" # after $ picoclaw model add -b https://api.openai.com/v1 -k sk-...
Defensive patterns
Strategy: retry
Validate before calling
u, err := url.Parse(strings.TrimSpace(apiBase))
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("--api-base must be a full URL like https://api.openai.com/v1, got %q", apiBase)
} Type guard
func isFetchModelsError(err error) bool {
return err != nil && strings.Contains(err.Error(), "fetch models:")
}
var unreachableErr *url.Error
isNetwork := errors.As(err, &unreachableErr) // inside the wrapped chain Try / catch
var entries []modelEntry
var err error
for attempt := 0; attempt < 3; attempt++ {
entries, err = fetchOpenAIModels(apiBase, apiKey)
var ue *url.Error
if err == nil || !errors.As(err, &ue) {
break // retry only transport-level failures; HTTP 4xx are permanent
}
time.Sleep(time.Duration(attempt+1) * 500 * time.Millisecond)
} Prevention
- Always include the scheme and the provider-documented prefix (usually ending in /v1)
- curl the /models endpoint once before scripting against it
- Prefer -m <model-id> to skip the network round-trip when you know the id
- Watch for proxies returning HTML with status 200 — fix the base URL, not the key
When it happens
Trigger: -b '' or -k ' ' passed as blank/whitespace; missing scheme in the base (api.openai.com/v1); wrong /v1 prefix so GET <base>/models 404s; 401/403 from an invalid key; self-signed TLS; HTML error pages or other non-JSON bodies the shape parser rejects.
Common situations: Providers whose documented base needs /v1 appended or removed; keys from a different account or project; corporate proxies rewriting responses; gateways returning HTML login pages; offline or firewalled environments.
Related errors
- no models returned by %s
- Failed to load config
- Failed to fetch config
- cannot found model '%s' in config
- requesting device code: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/0c957f045d0c951b.
Report an issue: GitHub.