siyuan-note/siyuan · error

new item template field [%s] option [%s] not found

Error message

new item template field [%s] option [%s] not found

What it means

For Select/MSelect Static-mode values, each selection.Content must resolve to an existing option on the key via key.GetOption(content). Selecting an option that was deleted or renamed is rejected, because the picker would render a dangling reference.

Source

Thrown at kernel/av/new_item_template.go:339

		}
		switch fieldValue.Mode {
		case NewItemFieldValueCurrentTime:
			if KeyTypeDate != key.Type {
				return fmt.Errorf("new item template field [%s] current time mode requires date type", keyID)
			}
			fieldValue.Value = nil
		case NewItemFieldValueStatic:
			if nil == fieldValue.Value {
				continue
			}
			fieldValue.Value, err = normalizeNewItemTemplateValue(fieldValue.Value, key)
			if nil != err {
				return fmt.Errorf("new item template field [%s] value is invalid: %w", keyID, err)
			}
			if KeyTypeSelect == key.Type || KeyTypeMSelect == key.Type {
				for _, selection := range fieldValue.Value.MSelect {
					if nil != selection && nil == key.GetOption(selection.Content) {
						return fmt.Errorf("new item template field [%s] option [%s] not found", keyID, selection.Content)
					}
				}
			}
		default:
			return fmt.Errorf("invalid new item template field value mode [%s]", fieldValue.Mode)
		}
		fieldValues[keyID] = fieldValue
	}
	if 0 == len(fieldValues) {
		itemTemplate.FieldValues = nil
	} else {
		itemTemplate.FieldValues = fieldValues
	}
	return nil
}

func normalizeNewItemTemplateValue(value *Value, key *Key) (*Value, error) {
	value = value.Clone()

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Refresh the option list client-side before saving and remap or drop stale selections.
  2. When renaming an option server-side, use RenameNewItemTemplateSelectOption (new_item_template.go:135) to keep templates in sync.
  3. When deleting an option server-side, use RemoveNewItemTemplateSelectOption (new_item_template.go:130) in the same transaction.

Example fix

// before — references a removed option
Value.MSelect = []*av.ValueSelect{{Content: "old-opt"}}
// after
Value.MSelect = []*av.ValueSelect{{Content: "renamed-opt"}}
Defensive patterns

Strategy: validation

Validate before calling

if key.Type == av.KeyTypeSelect || key.Type == av.KeyTypeMSelect {
    for _, sel := range value.MSelect {
        if sel != nil && key.GetOption(sel.Content) == nil {
            return fmt.Errorf("option [%s] not found", sel.Content)
        }
    }
}

Prevention

When it happens

Trigger: An option is deleted or renamed while the template editor is open; the client caches a stale option list; an import references options that do not exist on this key; concurrent option edits between two clients.

Common situations: Sync applying remote option changes locally; user reorganizing option list after the template was last saved; copy of a template between AVs whose option sets differ.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/8dc657636dd5a0dd. Report an issue: GitHub.