siyuan-note/siyuan · error

invalid sort position [%s]

Error message

invalid sort position [%s]

What it means

CreateDocByMd supports placing a new document before/after an existing sibling. When a sortTargetID is supplied, sortPosition must be exactly "before" or "after"; any other value (including empty and casing variants) triggers fmt.Errorf("invalid sort position [%s]").

Source

Thrown at kernel/model/file.go:1291

	transaction := &Transaction{DoOperations: []*Operation{{Action: "create", Data: tree}}}
	PerformTransactions(&[]*Transaction{transaction})
}

var createDocLock = sync.Mutex{}

func CreateDocByMd(boxID, p, title, md string, sorts []string, arg map[string]any) (tree *parse.Tree, err error) {
	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()

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Pass sortPosition as exactly "before" or "after" (lowercase) whenever sortTargetID is set.
  2. Omit both sortTargetID and sortPosition to append the document without positional placement.
  3. Validate the position string client-side before calling the API.

Example fix

// before
createDocWithMd({notebook, path, markdown, sortTargetID: target, sortPosition: "Before"});
// after
createDocWithMd({notebook, path, markdown, sortTargetID: target, sortPosition: "before"});
Defensive patterns

Strategy: validation

Validate before calling

if (sortTargetID && sortPosition !== "before" && sortPosition !== "after") {
  throw new Error('sortPosition must be "before" or "after"');
}

Prevention

When it happens

Trigger: Calling CreateDocByMd (API /api/filetree/createDocWithMd) with arg["sortTargetID"] set and arg["sortPosition"] not equal to "before" or "after".

Common situations: Plugin passing localized or capitalized position strings ('Before', 'top'); API scripts omitting sortPosition while setting sortTargetID; typos like 'befor'.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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