siyuan-note/siyuan · error

each option requires a nonempty name

Error message

each option requires a nonempty name

What it means

Every option supplied to the 'options' setting must have a non-empty, non-whitespace Name. SiYuan uses option names as the stored value of select cells, so an unnamed option would corrupt cell data and is rejected during validation.

Solutions

  1. Give every option a non-empty Name (trimmed) before sending
  2. Filter out null/incomplete entries from the array client-side
  3. Check the JSON property is exactly "name" (av.SelectOption field)

Example fix

// before
[{"color":"1"},{"name":"  "}]
// after
[{"name":"Todo","color":"1"},{"name":"Done","color":"3"}]
Defensive patterns

Strategy: validation

Validate before calling

const valid = opts => opts.every(o => o && typeof o.name === "string" && o.name.trim() !== "");
if (!valid(options)) throw new Error("all options need a nonempty name");

Prevention

When it happens

Trigger: Updating a select/mselect field's options where an array element is null or its Name is "", whitespace-only, or missing from the JSON payload.

Common situations: UI code that creates an option row before the user types a name and submits too early; importer producing options with only colors; JSON objects using a wrong property name (e.g. label instead of name) that decodes to an empty Name.

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

Appendix: source

Thrown at kernel/model/attribute_view_key_config.go:205

	}
	decoder := json.NewDecoder(bytes.NewReader(data))
	decoder.DisallowUnknownFields()
	return decoder.Decode(dest)
}

func updateAttributeViewKeyOptions(attrView *av.AttributeView, key *av.Key, op *Operation, setting string, value any) error {
	if "options" == setting {
		var options []*av.SelectOption
		if err := decodeAttributeViewKeyConfig(value, &options); nil != err {
			return err
		}
		if 0 == len(options) {
			return errors.New("options must not be empty; use optionRemove to delete existing options")
		}
		names := map[string]bool{}
		for _, option := range options {
			if nil == option || "" == strings.TrimSpace(option.Name) {
				return errors.New("each option requires a nonempty name")
			}
			if names[option.Name] {
				return errors.New("duplicate option name")
			}
			if attrView.FilterColorValue(option.Color) != option.Color {
				return errors.New("invalid option color")
			}
			names[option.Name] = true
		}
		op.Data = options
		return updateAttributeViewColumnOptions(op)
	}
	if "optionRemove" == setting {
		name, ok := value.(string)
		if !ok || nil == key.GetOption(name) {
			return errors.New("optionRemove must name an existing option")
		}
		op.Data = name

View on GitHub (pinned to 9f775e8a12)