siyuan-note/siyuan · error

Field [ ] must not be empty

Error message

Field [%s] must not be empty

What it means

repoRequestString extracts a string field from the decoded request fields. When trim is enabled and the field value trims down to an empty string, it rejects the request with 'Field [key] must not be empty'. It exists to enforce that required string parameters carry non-whitespace content.

Solutions

  1. Provide a non-empty value for the named field in the request JSON
  2. Trim-intent: check value.trim() !== '' before sending
  3. Review which key is named in the error and map it to the client form field
  4. If the field is truly optional, send it as JSON null or omit it rather than an empty string

Example fix

// before
body = JSON.stringify({ passphrase: '' })
// after
body = JSON.stringify({ passphrase: 'my-passphrase' })
Defensive patterns

Strategy: validation

Validate before calling

function requireNonEmpty(value: unknown, key: string): string {
  const s = typeof value === 'string' ? value.trim() : '';
  if (!s) throw new Error(`Field [${key}] must not be empty`);
  return s;
}

Type guard

function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.trim().length > 0; }

Try / catch

try { await post(url, body); } catch (e) { if (String(e).includes('must not be empty')) { highlightEmptyField(extractKey(e)); } }

Prevention

When it happens

Trigger: Calling a repo API endpoint whose decodeRequest uses repoRequestString with required=true (or with trim=true) and passing a value that is "", whitespace-only, or JSON null for the key.

Common situations: Frontend forms submitting empty inputs, copy-paste introducing trailing whitespace that is then trimmed away, or scripts sending placeholder empty strings for keys/passwords in repo operations.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at kernel/apicontract/repo.go:207

	Chunks  []string `json:"chunks"`  // 文件分块列表
}

func repoRequestFields(reader io.Reader, path string) (map[string]json.RawMessage, error) {
	fields, err := blockRequestFields(reader, path)
	if err != nil {
		return nil, errors.New(strings.ReplaceAll(err.Error(), "map[string]json.RawMessage", "map[string]interface {}"))
	}
	return fields, nil
}
func repoRequestString(fields map[string]json.RawMessage, key string, required, trim bool) (string, error) {
	value, err := legacyField[string](fields, key, "String", required)
	if err != nil {
		return "", err
	}
	if trim && len(fields[key]) > 0 && string(fields[key]) != "null" {
		value = strings.TrimSpace(value)
		if value == "" {
			return "", fmt.Errorf("Field [%s] must not be empty", key)
		}
	}
	return value, nil
}
func init() {
	SetRepoIndexRetentionDays.decodeRequest = func(reader io.Reader) (request SetRepoIndexRetentionDaysRequest, err error) {
		fields, err := repoRequestFields(reader, "/api/repo/setRepoIndexRetentionDays")
		if err != nil {
			return request, err
		}
		if request.Days, err = legacyField[float64](fields, "days", "Number", true); err != nil {
			return request, err
		}
		return request, nil
	}
	SetRetentionIndexesDaily.decodeRequest = func(reader io.Reader) (request SetRetentionIndexesDailyRequest, err error) {
		fields, err := repoRequestFields(reader, "/api/repo/setRetentionIndexesDaily")
		if err != nil {

View on GitHub (pinned to 9f775e8a12)