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

  1. Generate a new unique ID for the document path if one already exists.
  2. Check box.Exist(p) before calling create functions and generate an alternative path if it returns true.
  3. For retry logic, verify the document wasn't already created before re-attempting.
  4. 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

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


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