siyuan-note/siyuan · error
Conf.Language(1)
Error message
Conf.Language(1)
What it means
After depth validation, validateCreateDoc checks box.Exist(p); if the target path already exists in the notebook it returns errors.New(Conf.Language(1)): "Duplicated filename". Document paths in SiYuan must be unique within a notebook, so creating a doc at an occupied path is rejected before any file write.
Source
Thrown at kernel/model/file.go:2320
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 8641553a1f)
Solutions
- Check existence first via /api/filetree/getHPathByPath or /api/filetree/docExists... and reuse/rename if occupied
- Generate a fresh unique ID for the path (via /api/filetree/getID) before creating
- Append a distinguishing suffix (timestamp) to the title/path on retry
- Wrap creation in logic that treats this error as 'already created' and continues
Example fix
// before
await fetchPost('/api/filetree/createDocWithMd', {notebook, path: fixedPath, markdown});
// after
const exists = await fetchPost('/api/filetree/getHPathByPath', {notebook, path: fixedPath});
const path = exists.code === 0 ? fixedPath + '-' + Date.now() : fixedPath;
await fetchPost('/api/filetree/createDocWithMd', {notebook, path, markdown}); Defensive patterns
Strategy: validation
Validate before calling
async function pathIsFree(notebook, p) {
const r = await fetchPost('/api/filetree/getHPathByPath', {notebook, path: p});
return r.code !== 0; // non-zero means not found, i.e. free
} Try / catch
try {
await fetchPost('/api/filetree/createDocWithMd', {notebook, path, markdown});
} catch (e) {
if (String(e).includes('Duplicated filename')) {
// treat as already-created, or create with a fresh unique ID
}
} Prevention
- Always generate fresh IDs for new doc paths
- Make create operations idempotent: check existence before creating
- Avoid re-running import scripts without cleanup
When it happens
Trigger: POST /api/filetree/createDocWithMd or createDoc with a path equal to an existing document's path in that notebook (same ID/name base).
Common situations: Retry scripts re-running after a partial failure (doc already created on first run); imports run twice without cleanup; race conditions where two clients create the same-named doc concurrently; generating IDs deterministically so collisions occur.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/cb1d69ce0fd2b4be.
Report an issue: GitHub.