siyuan-note/siyuan · error

Field [ ] must not be empty

Error message

Field [%s] must not be empty

What it means

Fields marked with the trim constraint in export contracts are whitespace-trimmed, and if the trimmed string is empty, decodeExportFields returns "Field [%s] must not be empty". It catches values that are present but effectively blank — spaces, tabs, newlines — for fields the endpoint cannot operate on without content.

Solutions

  1. Supply a non-empty value for the field named in the error
  2. Trim/validate the value client-side before the request and reject empty input in your UI
  3. Fall back to a valid default when the primary value is blank
  4. Confirm with the API docs which fields are required and non-blank

Example fix

// before
const id = input.value.trim(); fetchPost("/api/export/exportMd", { id });
// after
const id = input.value.trim(); if (!id) return alert("id required"); fetchPost("/api/export/exportMd", { id });
Defensive patterns

Strategy: validation

Validate before calling

function requireNonBlank(payload, names) {
  for (const n of names) {
    if (typeof payload[n] === "string" && payload[n].trim() === "") throw new Error(`Field [${n}] must not be empty`);
  }
}
requireNonBlank(payload, ["id"]);

Type guard

const isNonBlankString = (v) => typeof v === "string" && v.trim().length > 0;

Try / catch

try { await exportApi(payload); } catch (e) { if (String(e).includes("must not be empty")) return alert("Please fill in all required inputs"); throw e; }

Prevention

When it happens

Trigger: Calling an export API with a required trim field set to "" or " " (whitespace only), e.g. an empty id, path, or title after trimming.

Common situations: Form inputs from the UI submitted without validation; string interpolation producing " " (e.g. ` ${undefined}` edge cases avoided but `${x}` empty); template defaults of empty string left unconfigured.

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

Appendix: source

Thrown at kernel/apicontract/export.go:258

			}
			return fmt.Errorf("Field [%s] is required", name)
		}
		if err := decodeRequestValue(raw, dest); err != nil {
			if has("ignoretype") || value.Type() == reflect.TypeFor[ExportTitleOptions]() && name == "addTitle" {
				dest.SetZero()
				continue
			}
			kind := dest.Kind()
			if kind == reflect.Pointer {
				kind = dest.Type().Elem().Kind()
			}
			kindName := map[reflect.Kind]string{reflect.String: "String", reflect.Bool: "Boolean", reflect.Float64: "Number", reflect.Slice: "Array"}[kind]
			return fmt.Errorf("Field [%s] should be of type [%s]", name, kindName)
		}
		if has("trim") {
			text := strings.TrimSpace(dest.String())
			if text == "" {
				return fmt.Errorf("Field [%s] must not be empty", name)
			}
			dest.SetString(text)
		}
	}
	return nil
}

func bindExportDecoder[Request, Data any](endpoint *Endpoint[Request, Data]) {
	endpoint.decodeRequest = func(reader io.Reader) (request Request, err error) {
		fields, err := blockRequestFields(reader, endpoint.Definition().Path)
		if err != nil {
			return request, err
		}
		err = decodeExportFields(reflect.ValueOf(&request).Elem(), fields)
		return request, err
	}
}

View on GitHub (pinned to 9f775e8a12)