siyuan-note/siyuan · warning
Duplicated filename
Error message
Duplicated filename
What it means
Thrown by validateCreateDoc when a document already exists at the given path. Conf.Language(1) = 'Duplicated filename'. The check uses box.Exist(p) which tests for the presence of a .sy file at that path. This is the final validation before the function returns success, after all other checks (title length, ID validity, dotfile, depth) have passed.
Source
Thrown at kernel/model/file.go:2293
parentID := path.Base(folder)
parentTree, loadErr := LoadTreeByBlockID(parentID)
if nil != loadErr {
logging.LogErrorf("get parent tree [%s] failed", parentID)
return nil, ErrBlockNotFound
}
parentPath := strings.TrimSuffix(parentTree.Path, ".sy")
if parentTree.Box != boxID || cleanBoxDocDir(parentPath) != cleanBoxDocDir(folder) {
logging.LogErrorf("parent tree [%s] does not match box [%s] and folder [%s]", parentID, boxID, folder)
return nil, ErrBlockNotFound
}
hPath = path.Join(parentTree.HPath, title)
}
if depth := strings.Count(p, "/"); 7 < depth && !Conf.FileTree.AllowCreateDeeper {
return nil, errors.New(Conf.Language(118))
}
if box.Exist(p) {
return nil, errors.New(Conf.Language(1))
}
ret = &createDocValidation{
box: box,
path: p,
title: title,
hPath: hPath,
id: util.GetTreeID(p),
folder: folder,
isEmpty: isEmpty,
}
return
}
func cleanBoxDocDir(p string) string {
return path.Clean("/" + strings.TrimPrefix(p, "/"))
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Generate a new unique ID for the document path if one already exists.
- Check box.Exist(p) before calling create functions and generate an alternative path if it returns true.
- For retry logic, verify the document wasn't already created before re-attempting.
- In concurrent scenarios, use the createDocLock (already held by CreateWithMarkdown) or coordinate ID generation to avoid collisions.
Example fix
// before
err := model.ValidateCreateDoc(boxID, p, title)
// after
box := conf.Box(boxID)
if box != nil && box.Exist(p) {
// generate a new unique ID/path
newID := util.NewNodeID()
p = path.Join(path.Dir(p), newID+".sy")
}
err := model.ValidateCreateDoc(boxID, p, title) Defensive patterns
Strategy: validation
Validate before calling
// Pre-check: ensure no document exists at the target path
box := conf.Box(boxID)
if box != nil && box.Exist(p) {
// generate a new unique ID/path
newID := util.NewNodeID()
p = path.Join(path.Dir(p), newID+".sy")
} Type guard
func pathIsAvailable(boxID, p string) bool {
box := conf.Box(boxID)
if box == nil {
return false
}
return !box.Exist(p)
} Prevention
- Check box.Exist(p) before calling create functions and generate an alternative path if occupied.
- Generate fresh unique IDs for each document to avoid path collisions.
- For retry logic, verify the document wasn't already created before re-attempting.
- In concurrent scenarios, rely on createDocLock to serialize ID generation.
When it happens
Trigger: Calling create/validate functions with a path where a .sy file already exists. Common when the caller reuses an existing document ID/path, or when a concurrent create operation races to create the same path.
Common situations: A create-with-ID call uses an ID that already exists (duplicate ID generation or collision). A retry of a previously successful create. A concurrent batch create where two items resolve to the same path. A UI 'create document here' action where a document with the same generated ID already exists.
Related errors
- Untitled
- Cannot create a file starting with .
- custom emoji name must not be empty
- duplicated new item template id [%s]
- invalid path
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/a0987af131a39336.
Report an issue: GitHub.