siyuan-note/siyuan · error

duplicated new item template id [%s]

Error message

duplicated new item template id [%s]

What it means

Two entries in config.Templates carry the same ID. The validator tracks seen IDs in a map (new_item_template.go:69) and rejects the second occurrence, because persisted template references (DefaultTemplateID, per-row bindings) require uniqueness within the AV.

Source

Thrown at kernel/av/new_item_template.go:70

			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 {
			return err
		}
		templates = append(templates, itemTemplate)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Regenerate the ID for any duplicated template before submitting.
  2. Dedupe template IDs on the client before the save call.
  3. When cloning in UI code, always assign a freshly generated node ID.

Example fix

// before
Templates: []*av.NewItemTemplate{{ID: "20240812...abc"}, {ID: "20240812...abc"}}
// after
Templates: []*av.NewItemTemplate{{ID: "20240812...abc"}, {ID: "20240812...def"}}
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, t := range config.Templates {
    if t == nil {
        continue
    }
    if seen[t.ID] {
        return fmt.Errorf("duplicated new item template id [%s]", t.ID)
    }
    seen[t.ID] = true
}

Prevention

When it happens

Trigger: Frontend clones a template in the editor without minting a new ID; an import payload contains duplicated IDs; copy-paste of a template JSON followed by save.

Common situations: Client-side clone button that copies all fields including ID; sync conflict resolution that duplicated a template; manually authored config in tests.

Related errors


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