siyuan-note/siyuan · error
duplicated new item template id
Error message
duplicated new item template id [%s]
What it means
Template IDs within one NewItemTemplatesConfig must be unique; SetNewItemTemplates tracks seen IDs in templateIDs map and rejects duplicates with this error naming the repeated ID. Duplicate IDs would make default-template resolution and lookup ambiguous.
Solutions
- Assign a distinct valid node ID to every template in the config.
- Deduplicate by ID before calling SetNewItemTemplates (keep the last or first occurrence deliberately).
- When cloning a template for editing, regenerate its ID on save.
Example fix
// before
{id: "20240918120000-abcdef0123456789", name: "A"}, {id: "20240918120000-abcdef0123456789", name: "B"}
// after
{id: "20240918120000-abcdef0123456789", name: "A"}, {id: "20240918120001-0123456789abcdef", name: "B"} Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]bool{}
for _, t := range cfg.Templates {
if seen[t.ID] { return fmt.Errorf("duplicate template id %s", t.ID) }
seen[t.ID] = true
} Prevention
- Regenerate the ID whenever duplicating a template
- Deduplicate configs before merging sources
- Enforce uniqueness in the settings UI at edit time
When it happens
Trigger: Submitting a config where two or more templates share the same ID — commonly from copying an existing template entry without generating a new ID.
Common situations: Duplicating a template row in the settings UI; merging configs from two sources; round-tripping a config where a new template reused the old ID.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- duplicate source ID [ ]
- duplicate workspace attribute view builtin color update
- duplicated attribute view custom color index
- filter nesting depth exceeds the maximum allowed
- invalid new item template id
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/2abf76d2ae76cf71.
Report an issue: GitHub.
Appendix: 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 9f775e8a12)