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

  1. Check existence first via /api/filetree/getHPathByPath or /api/filetree/docExists... and reuse/rename if occupied
  2. Generate a fresh unique ID for the path (via /api/filetree/getID) before creating
  3. Append a distinguishing suffix (timestamp) to the title/path on retry
  4. 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

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.