siyuan-note/siyuan · error
target ID [%s] must not be included in source IDs
Error message
target ID [%s] must not be included in source IDs
What it means
The reorder operation moves source documents relative to a target document, so the target itself must not be part of the moved set. validateReorderArgs iterates the sourceIDs and fails with this error if any source equals targetID. Allowing it would make 'insert [target] before target' ill-defined.
Source
Thrown at kernel/model/file.go:2727
ret.Changed = true
ret.Notebook = box.ID
ret.ParentPath = parentPath
IncSync()
pushFiletreeSortChanged(sortIDs)
return
}
func validateReorderArgs(sourceIDs []string, targetID, position string) error {
if 1 > len(sourceIDs) {
return errors.New("source IDs must not be empty")
}
if "before" != position && "after" != position {
return fmt.Errorf("invalid reorder position [%s]", position)
}
seen := map[string]struct{}{}
for _, sourceID := range sourceIDs {
if sourceID == targetID {
return fmt.Errorf("target ID [%s] must not be included in source IDs", targetID)
}
if _, ok := seen[sourceID]; ok {
return fmt.Errorf("duplicate source ID [%s]", sourceID)
}
seen[sourceID] = struct{}{}
}
return nil
}
func isSortableDocument(tree *treenode.BlockTree) bool {
return nil != tree && tree.ID == tree.RootID && "d" == tree.Type && !IsBoxDoc(tree.BoxID, tree.RootID)
}
func loadSiblingCustomOrder(boxID, parentPath string, fullSortIDs map[string]int) (ret []string, err error) {
absParentPath := filepath.Join(util.DataDir, boxID, parentPath)
files, err := os.ReadDir(absParentPath)
if nil != err {
return nil, fmt.Errorf("read dir [%s] failed: %w", absParentPath, err)View on GitHub (pinned to 8641553a1f)
Solutions
- Filter targetID out of the sourceIDs list before calling: sources := sources without targetID
- Validate in the caller and return a no-op when targetID appears among the sources (a drop onto itself does nothing)
- Fix the drag/selection code so the drop target is excluded from the dragged set
Example fix
// before
err := model.ReorderDocs(ids, targetID, position) // ids may contain targetID
// after
filtered := ids[:0]
for _, id := range ids {
if id != targetID {
filtered = append(filtered, id)
}
}
err := model.ReorderDocs(filtered, targetID, position) Defensive patterns
Strategy: validation
Validate before calling
for _, id := range sourceIDs {
if id == targetID {
return errors.New("target must not appear in source IDs")
}
} Type guard
func excludesTarget(sourceIDs []string, targetID string) bool {
for _, id := range sourceIDs {
if id == targetID { return false }
}
return true
} Try / catch
if !excludesTarget(sourceIDs, targetID) {
return nil // drop onto itself: treat as no-op
} Prevention
- Filter the drop target out of the dragged set in drag-and-drop handlers
- Treat 'sources containing target' as a no-op rather than an API call
- Add a test asserting the target is never included in sources
When it happens
Trigger: Calling ReorderDocs(["doc-a", "doc-b"], "doc-a", "before") where one source ID equals the target ID; a frontend drag handler that appends the drop target into the dragged-IDs list; scripted multi-select that accidentally includes the anchor element.
Common situations: UI code selecting a range that includes the drop anchor; automation scripts filtering IDs incorrectly; plugins implementing custom drag-and-drop that include the hovered element among the dragged items.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- source IDs must not be empty
- duplicate source ID [%s]
- wrong layout type
- filter nesting depth exceeds the maximum allowed
- invalid session id
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/58731dbd75a0c0b0.
Report an issue: GitHub.