siyuan-note/siyuan · error

Field [ ] must not be empty

Error message

Field [%s] must not be empty

What it means

For /api/block/checkBlockRef, required array fields (ids under scope "blocks", paths under scope "documents") must contain at least one element. The kernel decodes the array successfully but rejects it with this error when the nonempty requirement applies and the array length is zero. Optional fields (exactIDs, deletedIDs) are exempt from this check.

Solutions

  1. Ensure ids (or paths for scope "documents") contains at least one valid block/document ID before calling
  2. Skip the API call entirely when the caller's selection is empty
  3. If checking optional subsets, move those IDs into exactIDs/deletedIDs and keep ids populated

Example fix

// before
await fetchPost("/api/block/checkBlockRef", { scope: "blocks", ids: [] });
// after
if (ids.length > 0) {
  await fetchPost("/api/block/checkBlockRef", { scope: "blocks", ids });
}
Defensive patterns

Strategy: validation

Validate before calling

if (payload.ids.length === 0) return; // nothing to check
await fetchPost('/api/block/checkBlockRef', payload);

Type guard

const hasTargets = (p) => Array.isArray(p.ids) && p.ids.length > 0;

Try / catch

try { await fetchPost('/api/block/checkBlockRef', payload); } catch (e) { if (/must not be empty/.test(e?.message)) return null; throw e; }

Prevention

When it happens

Trigger: POST /api/block/checkBlockRef with scope "blocks" and "ids": [], or scope "documents" with "paths": []. Passing "ids": [] while relying on the default scope (which defaults to "blocks") also triggers it.

Common situations: Filtering a block list produced an empty selection that was passed through unchanged; upstream code collected matching IDs into an array that ended up empty; automations that call the check endpoint unconditionally before any selection exists.

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/fb63a428ec776dfe. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/block_remaining.go:92

		}
	}
	if strings.TrimSpace(request.Scope) == "" {
		request.Scope = "blocks"
	}
	readArray := func(key string, required, nonempty bool) ([]string, error) {
		raw, present := fields[key]
		if !present && !required {
			return nil, nil
		}
		if !present || bytes.Equal(raw, []byte("null")) {
			return nil, fmt.Errorf("Field [%s] is required", key)
		}
		var entries []json.RawMessage
		if json.Unmarshal(raw, &entries) != nil {
			return nil, fmt.Errorf("Field [%s] should be of type [Array]", key)
		}
		if nonempty && len(entries) == 0 {
			return nil, fmt.Errorf("Field [%s] must not be empty", key)
		}
		var values []string
		seen := map[string]bool{}
		for _, entry := range entries {
			var value string
			if json.Unmarshal(entry, &value) != nil || strings.TrimSpace(value) == "" {
				return nil, fmt.Errorf("Field [%s] should contain non-empty strings", key)
			}
			if !seen[value] {
				values = append(values, value)
				seen[value] = true
			}
		}
		return values, nil
	}
	switch request.Scope {
	case "blocks":
		if request.IDs, err = readArray("ids", true, true); err != nil {

View on GitHub (pinned to 9f775e8a12)