siyuan-note/siyuan · error

invalid new item template id

Error message

invalid new item template id [%s]

What it means

SetNewItemTemplates requires each template's ID to match ast.IsNodeIDPattern (a valid SiYuan node ID like 20240101120000-abcdefgh). IDs failing this pattern make the config invalid and abort the update, with the offending ID embedded via %s.

Solutions

  1. Assign a valid node-format ID (yyyymmddhhmmss-16hexchars) to every template.
  2. Use the kernel's treenode/id helper to generate IDs instead of hand-rolling them.
  3. Check IDs with ast.IsNodeIDPattern before calling SetNewItemTemplates.

Example fix

// before
{id: "tpl-1"}
// after
{id: "20240918120000-abcdef0123456789"}
Defensive patterns

Strategy: validation

Validate before calling

for _, t := range cfg.Templates {
	if !ast.IsNodeIDPattern(t.ID) { return fmt.Errorf("bad template id %s", t.ID) }
}

Prevention

When it happens

Trigger: Passing a template with an empty, custom, or malformed ID (wrong length, missing dash separator, non-hex suffix).

Common situations: Generating IDs client-side with random strings instead of the SiYuan ID format; copying truncated IDs; legacy or hand-crafted config files.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/4edfd2b95edeabe2. Report an issue: GitHub.

Appendix: source

Thrown at kernel/av/new_item_template.go:67

		}
		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)
			itemTemplate.SaveLocation.PathTemplate = strings.TrimSpace(itemTemplate.SaveLocation.PathTemplate)
		}
		if err := av.normalizeNewItemTemplateFieldValues(itemTemplate); nil != err {

View on GitHub (pinned to 9f775e8a12)