siyuan-note/siyuan · error

Field [mode] must be 0 or 1

Error message

Field [mode] must be 0 or 1

What it means

When the optional mode field is supplied to the bazaar install endpoint, its numeric value must be exactly 0 or 1. Any other number (or non-integer numeric JSON) is rejected by the decoder before reaching the handler, since mode is a two-value selector, not a free integer.

Solutions

  1. Set mode to exactly 0 (app) or 1 (plugin/frontend context).
  2. Map your internal value to the supported 0/1 domain before sending.
  3. If you need more states than 0/1, omit mode/modeOS entirely instead of inventing values.
  4. Log and clamp the value at the client boundary.

Example fix

// before
{"packageName": "siyuan-plugin-x", "mode": 2, "modeOS": false}
// after
{"packageName": "siyuan-plugin-x", "mode": 1, "modeOS": false}
Defensive patterns

Strategy: validation

Validate before calling

if (payload.mode !== undefined && ![0, 1].includes(payload.mode)) {
  throw new Error("mode must be 0 or 1");
}

Type guard

const isMode = (v) => v === 0 || v === 1;

Prevention

When it happens

Trigger: POSTing to the bazaar install endpoint with {"packageName":"x","mode":2,"modeOS":true} or mode values like -1, 1.5, or a numeric string "0" sent as an actual number.

Common situations: Clients guessing mode semantics and using 2 for 'both', enum-like constants from other APIs (0/1/2 conventions), or mapping internal flags (bitmasks) directly onto mode.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/056ca953e963dd41. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/bazaar.go:928

		if request.PackageName, err = bazaarString(fields, "packageName", true, true); err != nil {
			return request, err
		}
		_, hasMode := fields["mode"]
		_, hasModeOS := fields["modeOS"]
		if hasMode != hasModeOS {
			return request, errors.New("Fields [mode] and [modeOS] must be provided together")
		}
		if hasMode {
			mode, parseErr := legacyField[float64](fields, "mode", "Number", true)
			if parseErr != nil {
				return request, parseErr
			}
			modeOS, parseErr := legacyField[bool](fields, "modeOS", "Boolean", true)
			if parseErr != nil {
				return request, parseErr
			}
			if mode != 0 && mode != 1 {
				return request, errors.New("Field [mode] must be 0 or 1")
			}
			request.Mode = &mode
			request.ModeOS = &modeOS
		}
		return request, nil
	}
	UninstallBazaarTheme.decodeRequest = func(reader io.Reader) (request UninstallBazaarThemeRequest, err error) {
		fields, err := bazaarRequestFields(reader, "/api/bazaar/uninstallBazaarTheme")
		if err != nil {
			return request, err
		}
		if request.Frontend, err = bazaarString(fields, "frontend", false, false); err != nil {
			return request, err
		}
		if request.Keyword, err = bazaarString(fields, "keyword", false, false); err != nil {
			return request, err
		}
		if request.PackageName, err = bazaarString(fields, "packageName", true, true); err != nil {

View on GitHub (pinned to 9f775e8a12)