siyuan-note/siyuan · error

invalid null bazaar index

Error message

invalid null bazaar index

What it means

parseBazaarIndex requires the fetched index to be a non-empty JSON object. json.Unmarshal into map[string]json.RawMessage succeeded, but the resulting map is nil/empty (e.g. body was literal "null", empty, or whitespace-only), so there is no bazaar index content at all. The library rejects such a body instead of treating it as an empty marketplace.

Source

Thrown at kernel/bazaar/index.go:202

	u := fmt.Sprintf("%s%s?t=%d", bazaarIndexStatServer, indexPath, timeBucket)
	buf := &bytes.Buffer{}
	resp, err := httpclient.NewBrowserRequest().SetRetryCount(0).SetContext(ctx).SetOutput(buf).Get(u)
	if nil != err {
		return nil, err
	}
	if 200 != resp.StatusCode {
		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	}
	return parseBazaarIndex(buf.Bytes())
}

func parseBazaarIndex(data []byte) (ret *bazaarIndexSnapshot, err error) {
	raw := map[string]json.RawMessage{}
	if err = json.Unmarshal(data, &raw); nil != err {
		return nil, err
	}
	if nil == raw {
		return nil, errors.New("invalid null bazaar index")
	}
	ret = &bazaarIndexSnapshot{
		packages:    map[string]*bazaarIndexPackage{},
		legacyStats: map[string]*bazaarStats{},
	}

	metaRaw, hasMeta := raw["meta"]
	packagesRaw, hasPackages := raw["packages"]
	if hasMeta {
		if err = json.Unmarshal(metaRaw, &ret.meta); nil != err {
			return nil, err
		}
		if 2 > ret.meta.Schema {
			return nil, fmt.Errorf("invalid bazaar index schema: %d", ret.meta.Schema)
		}
		if "" == strings.TrimSpace(ret.meta.Generation) || 1 > ret.meta.PublishedAt {
			return nil, errors.New("invalid bazaar index generation metadata")
		}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Inspect the raw bytes the CDN returns for the index URL (curl it) and fix the server-side publication so it serves a real index object
  2. If a proxy/captive portal is returning 200 with an empty body, restore direct network access
  3. Retry after the bazaar deploy completes; the refresh loop will fetch the corrected index
  4. If you control the publisher, guard the deploy pipeline against uploading null/empty index files
Defensive patterns

Strategy: validation

Validate before calling

// validate the body before trusting the index
var probe map[string]json.RawMessage
if json.Unmarshal(body, &probe) != nil || len(probe) == 0 {
    return errors.New("empty or null index body")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "invalid null bazaar index") {
    // 200 with empty/null body: treat as upstream publish failure, keep cached index
}

Prevention

When it happens

Trigger: fetchBazaarIndexPath receives HTTP 200 with a body that unmarshals into a nil map — literally "null", an empty file served with 200, or a zero-length response.

Common situations: CDN serving an empty object/file during a broken deploy; a proxy returning 200 with an empty body (captive portal or intercepting middleware); misconfigured object storage publishing a null placeholder index.

Related errors


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