siyuan-note/siyuan · error

sort target ID is required when sort position is specified

Error message

sort target ID is required when sort position is specified

What it means

CreateDocByMd in kernel/model/file.go:1298 lets callers position a new document relative to an existing sibling document. The sort target ID (sortTargetID) and the sort position (sortPosition) are a paired argument set: a position is meaningless without the reference document it is relative to. When a sortPosition is supplied but sortTargetID is empty, the function rejects the request instead of guessing a placement.

Source

Thrown at kernel/model/file.go:1298

	createDocLock.Lock()
	defer createDocLock.Unlock()

	box, err := getOpenedBox(boxID)
	if nil != err {
		return
	}
	sortTargetID, _ := arg["sortTargetID"].(string)
	sortPosition, _ := arg["sortPosition"].(string)
	if "" != sortTargetID {
		if "before" != sortPosition && "after" != sortPosition {
			return nil, fmt.Errorf("invalid sort position [%s]", sortPosition)
		}
		target := treenode.GetBlockTree(sortTargetID)
		if !isSortableDocument(target) || target.BoxID != boxID || path.Dir(target.Path) != path.Dir(p) {
			return nil, fmt.Errorf("sort target document [%s] is not a sibling of the new document", sortTargetID)
		}
	} else if "" != sortPosition {
		return nil, errors.New("sort target ID is required when sort position is specified")
	}

	luteEngine := util.NewLute()
	luteEngine.SetHTMLTag2TextMark(true)
	dom := luteEngine.Md2BlockDOM(md, false)
	tree, err = createDoc(box.ID, p, title, dom, false)
	if err != nil {
		return
	}

	FlushTxQueue()
	if "" != sortTargetID {
		if _, sortErr := ReorderDocs([]string{tree.ID}, sortTargetID, sortPosition); nil != sortErr {
			logging.LogErrorf("reorder created document [%s] failed: %s", tree.ID, sortErr)
			box.setSortByConf(path.Dir(tree.Path), tree.ID)
		}
	} else if 0 < len(sorts) {
		ChangeFileTreeSort(box.ID, sorts)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Pass the ID of the sibling document the new doc should be placed relative to (sortTargetID) together with sortPosition.
  2. If you do not need positional placement, omit sortPosition entirely and pass the parent path (hPath/parentID) instead.
  3. Verify the target ID is a valid, sortable sibling document in the same notebook and same parent path (the next validation after this one checks isSortableDocument, BoxID, and sibling dir).

Example fix

// before
createDocByMd(boxID, hPath, md, {sortPosition: "after"});
// after
createDocByMd(boxID, hPath, md, {sortPosition: "after", sortTargetID: "20240101120000-abcdefg"});
Defensive patterns

Strategy: validation

Validate before calling

if (sortPosition && !sortTargetID) {
  throw new Error("sortTargetID is required when sortPosition is set");
}
const target = await getBlockTreeByID(sortTargetID); // must exist, be sortable, same notebook & parent dir

Type guard

function hasValidSortTarget(args) {
  return !args.sortPosition || (typeof args.sortTargetID === "string" && args.sortTargetID.length > 0);
}

Try / catch

try {
  await createDocByMd(boxID, hPath, md, {sortPosition, sortTargetID});
} catch (e) {
  if (String(e.msg).includes("sort target ID is required")) {
    await createDocByMd(boxID, hPath, md, {}); // fall back to default placement
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling CreateDocByMd (or the /api/filetree/createDocWithMdByPosition-style endpoints that wrap it) with a non-empty sortPosition (e.g. 'before', 'after', or an index) while leaving the sortTargetID/sortTarget argument empty string.

Common situations: Plugin or automation scripts that build the request payload programmatically and include sortPosition copied from a template but never set the target ID; frontends that compute position from a drag-drop but lose the dragged-over document's ID; API consumers porting code from an older SiYuan version where position could be specified standalone.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/7f6f597307af00ca. Report an issue: GitHub.