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

  1. Retry the refresh — likely a transient upstream/proxy problem
  2. Bypass any proxy/captive portal and check the raw endpoint response
  3. If the upstream API shape changed, update SiYuan to a version whose decoder matches the new response
  4. 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

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


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/5961d21c8363f115. Report an issue: GitHub.