siyuan-note/siyuan · warning
empty catalog
Error message
empty catalog
What it means
The models.dev catalog response decoded successfully as JSON but contained zero providers, which is treated as an invalid catalog. A genuinely useful catalog always lists providers; an empty map means the upstream served an empty/degenerate payload, so fetchModelsDevContextCatalog refuses to adopt it.
Source
Thrown at kernel/agent/modelmeta_online.go:204
if err != nil {
return nil, err
}
resp, err := httpclient.NewUserAgentClient(nil).Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
providers := map[string]modelsDevProvider{}
limited := io.LimitReader(resp.Body, modelsDevCatalogMaxBytes+1)
if err = json.NewDecoder(limited).Decode(&providers); err != nil {
return nil, err
}
if len(providers) == 0 {
return nil, errors.New("empty catalog")
}
catalog := &modelsDevContextCatalog{
providers: map[string]*modelsDevProviderCatalog{},
models: map[string]int{},
suffixes: map[string]int{},
}
ambiguousModels := map[string]bool{}
ambiguousSuffixes := map[string]bool{}
for providerID, provider := range providers {
providerCatalog := &modelsDevProviderCatalog{
models: map[string]int{},
suffixes: map[string]int{},
}
providerAmbiguousSuffixes := map[string]bool{}
for name, model := range provider.Models {
limit := model.Limit.Context
if limit < 1 || maxModelContextLength < limit {View on GitHub (pinned to 8641553a1f)
Solutions
- Retry the refresh — likely a transient upstream/proxy problem
- Bypass any proxy/captive portal and check the raw endpoint response
- If the upstream API shape changed, update SiYuan to a version whose decoder matches the new response
- Keep using the previously cached catalog if available
Defensive patterns
Strategy: fallback
Validate before calling
if resp.StatusCode == http.StatusOK && len(body) < 3 { return nil, errors.New("suspiciously small catalog response") } Try / catch
catalog, err := fetchModelsDevContextCatalog(ctx)
if err != nil { catalog = lastKnownGoodCatalog }
if len(catalog.Providers) == 0 { /* surface degraded-metadata warning to user */ } Prevention
- Cache the last good catalog and only replace it when the new one passes validation
- Detect captive-portal/proxy stub responses before parsing
- Alert on sudden catalog size changes (e.g. providers count dropping to 0)
When it happens
Trigger: The catalog endpoint returns 200 with a valid JSON object that has no provider entries — e.g. an empty object '{}' response from a misbehaving proxy/captive portal or an upstream API change.
Common situations: Captive portal or proxy returning 200 with an empty/stub body; upstream API renamed its response shape so the decoder matches nothing; testing against a stubbed endpoint.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- unexpected status code: %d
- read body failed: %s
- version request returned HTTP " + response.status
- authentication probe returned HTTP " + response.status
- boot progress request returned HTTP " + response.status
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/5961d21c8363f115.
Report an issue: GitHub.