siyuan-note/siyuan · error

new item template name is empty

Error message

new item template name is empty

What it means

Every new-item template must carry a non-empty Name; SetNewItemTemplates rejects the whole config when any template's Name trims to "". The Name is what users see when picking a template for new rows.

Solutions

  1. Provide a non-empty, non-whitespace Name for every template in the config.
  2. Validate names client-side before submitting the template configuration.
  3. Fall back to a generated default name (e.g. 'Template 1') when the user left it blank.

Example fix

// before
cfg.Templates = []*av.NewItemTemplate{{ID: "20240101120000-abc"}}
// after
cfg.Templates = []*av.NewItemTemplate{{ID: "20240101120000-abc", Name: "Default"}}
Defensive patterns

Strategy: validation

Validate before calling

for _, t := range cfg.Templates {
	if strings.TrimSpace(t.Name) == "" { return errors.New("template name required") }
}

Prevention

When it happens

Trigger: Calling SetNewItemTemplates with a template whose Name is empty or consists only of whitespace (it is strings.TrimSpace'd before the check).

Common situations: UI form allowing an empty template name; JSON payloads omitting the name field; programmatically generated templates without a label.

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

Appendix: source

Thrown at kernel/av/new_item_template.go:64

	for _, itemTemplate := range config.Templates {
		if nil == itemTemplate {
			continue
		}
		itemTemplate = cloneNewItemTemplate(itemTemplate)
		if nil == itemTemplate {
			return errors.New("clone new item template failed")
		}
		itemTemplate.Name = strings.TrimSpace(itemTemplate.Name)
		itemTemplate.Icon = strings.TrimSpace(itemTemplate.Icon)
		if filteredIcon, valid := util.FilterIconValue(itemTemplate.Icon); valid {
			itemTemplate.Icon = filteredIcon
		} else {
			// 非法图标值置空,防止存储可执行标记
			// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-vx5w-qrvp-mmcq
			itemTemplate.Icon = ""
		}
		if "" == itemTemplate.Name {
			return errors.New("new item template name is empty")
		}
		if !ast.IsNodeIDPattern(itemTemplate.ID) {
			return fmt.Errorf("invalid new item template id [%s]", itemTemplate.ID)
		}
		if templateIDs[itemTemplate.ID] {
			return fmt.Errorf("duplicated new item template id [%s]", itemTemplate.ID)
		}
		templateIDs[itemTemplate.ID] = true
		if NewItemTargetDetached != itemTemplate.TargetType && NewItemTargetDocument != itemTemplate.TargetType {
			return fmt.Errorf("invalid new item template target type [%s]", itemTemplate.TargetType)
		}
		if NewItemTargetDocument != itemTemplate.TargetType {
			itemTemplate.Icon = ""
			itemTemplate.HideInFileTree = false
		}
		itemTemplate.ContentTemplatePath = strings.TrimSpace(itemTemplate.ContentTemplatePath)
		if nil != itemTemplate.SaveLocation {
			itemTemplate.SaveLocation.BoxID = strings.TrimSpace(itemTemplate.SaveLocation.BoxID)

View on GitHub (pinned to 9f775e8a12)