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
- Provide a non-empty, non-whitespace Name for every template in the config.
- Validate names client-side before submitting the template configuration.
- 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
- Require a name in the template-editing UI before save
- Trim names client-side to match the kernel's TrimSpace behavior
- Auto-generate a fallback name when the field is blank
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
- duplicated new item template id
- filter nesting depth exceeds the maximum allowed
- invalid new item template id
- wrong layout type
- all asset mappings failed
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)