siyuan-note/siyuan · error

Field [ ] is required

Error message

Field [%s] is required

What it means

For string (or *string) fields of the multipart request struct, DecodeMultipart looks up form.Value by the api tag name; if no text value with that name was submitted and the field is not tagged optional, it returns "Field [<name>] is required". This is contract-level required-field validation for form text fields.

Solutions

  1. Send the missing value in the multipart form under the exact field name from the `api` tag.
  2. If the field is optional, change the struct tag to include ,optional, (e.g. `api:"note,optional"`).
  3. Compare the client's submitted field names with the endpoint's request struct and align them.

Example fix

// before
formData.append("title", ""); // or omitted entirely
// after
formData.append("title", "My title");
Defensive patterns

Strategy: validation

Validate before calling

function requireField(formData, name) {
  const v = formData.get(name);
  if (v == null || v === "") throw new Error("field '" + name + "' is required");
}

Type guard

const hasNonEmptyValue = (fd, n) => { const v = fd.get(n); return typeof v === "string" && v.length > 0; };

Try / catch

try { await submit(url, formData); } catch (e) { if (/Field \[(.+)\] is required/.test(String(e))) { showFieldError(e.match(/\[(.+)\]/)[1]); return; } throw e; }

Prevention

When it happens

Trigger: Submitting a multipart form to an endpoint whose request struct declares a required string field (no ,optional, in the api tag) while the client omits that value or sends it under a different name.

Common situations: A required form input was left blank; the client renamed the input's name attribute; API change added a new required field that older clients do not send.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at kernel/apicontract/multipart.go:86

		switch field.Type {
		case reflect.TypeFor[*multipart.FileHeader](), reflect.TypeFor[[]*multipart.FileHeader]():
			files := form.File[name]
			if len(files) == 0 {
				if !optional {
					return request, fmt.Errorf("%s not found", name)
				}
				continue
			}
			if field.Type.Kind() == reflect.Slice {
				value.Field(i).Set(reflect.ValueOf(files))
			} else {
				value.Field(i).Set(reflect.ValueOf(files[0]))
			}
		case reflect.TypeFor[string](), reflect.TypeFor[*string]():
			values := form.Value[name]
			if len(values) == 0 {
				if !optional {
					return request, fmt.Errorf("Field [%s] is required", name)
				}
				continue
			}
			if field.Type.Kind() == reflect.Pointer {
				text := reflect.New(field.Type.Elem())
				text.Elem().SetString(values[0])
				value.Field(i).Set(text)
			} else {
				value.Field(i).SetString(values[0])
			}
		default:
			return request, fmt.Errorf("unsupported multipart field: %s", name)
		}
	}
	return
}

View on GitHub (pinned to 9f775e8a12)