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
- Give every option a non-empty Name (trimmed) before sending
- Filter out null/incomplete entries from the array client-side
- 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
- Disable the submit button until every option row has a name
- Trim and check names before serialization
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
- new option name must not be empty
- options must not be empty; use optionRemove to delete…
- at least one visible view is required
- attribute view custom color index
- attribute view custom color must not be null
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 = nameView on GitHub (pinned to 9f775e8a12)