{"record":{"id":"58731dbd75a0c0b0","repo":"siyuan-note/siyuan","slug":"target-id-s-must-not-be-included-in-source-ids","errorCode":null,"errorMessage":"target ID [%s] must not be included in source IDs","messagePattern":"target ID \\[(.+?)\\] must not be included in source IDs","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":2727,"sourceCode":"\tret.Changed = true\n\tret.Notebook = box.ID\n\tret.ParentPath = parentPath\n\tIncSync()\n\tpushFiletreeSortChanged(sortIDs)\n\treturn\n}\n\nfunc validateReorderArgs(sourceIDs []string, targetID, position string) error {\n\tif 1 > len(sourceIDs) {\n\t\treturn errors.New(\"source IDs must not be empty\")\n\t}\n\tif \"before\" != position && \"after\" != position {\n\t\treturn fmt.Errorf(\"invalid reorder position [%s]\", position)\n\t}\n\tseen := map[string]struct{}{}\n\tfor _, sourceID := range sourceIDs {\n\t\tif sourceID == targetID {\n\t\t\treturn fmt.Errorf(\"target ID [%s] must not be included in source IDs\", targetID)\n\t\t}\n\t\tif _, ok := seen[sourceID]; ok {\n\t\t\treturn fmt.Errorf(\"duplicate source ID [%s]\", sourceID)\n\t\t}\n\t\tseen[sourceID] = struct{}{}\n\t}\n\treturn nil\n}\n\nfunc isSortableDocument(tree *treenode.BlockTree) bool {\n\treturn nil != tree && tree.ID == tree.RootID && \"d\" == tree.Type && !IsBoxDoc(tree.BoxID, tree.RootID)\n}\n\nfunc loadSiblingCustomOrder(boxID, parentPath string, fullSortIDs map[string]int) (ret []string, err error) {\n\tabsParentPath := filepath.Join(util.DataDir, boxID, parentPath)\n\tfiles, err := os.ReadDir(absParentPath)\n\tif nil != err {\n\t\treturn nil, fmt.Errorf(\"read dir [%s] failed: %w\", absParentPath, err)","sourceCodeStart":2709,"sourceCodeEnd":2745,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/file.go#L2709-L2745","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nerr := model.ReorderDocs(ids, targetID, position) // ids may contain targetID\n// after\nfiltered := ids[:0]\nfor _, id := range ids {\n    if id != targetID {\n        filtered = append(filtered, id)\n    }\n}\nerr := model.ReorderDocs(filtered, targetID, position)","handlingStrategy":"validation","validationCode":"for _, id := range sourceIDs {\n    if id == targetID {\n        return errors.New(\"target must not appear in source IDs\")\n    }\n}","typeGuard":"func excludesTarget(sourceIDs []string, targetID string) bool {\n    for _, id := range sourceIDs {\n        if id == targetID { return false }\n    }\n    return true\n}","tryCatchPattern":"if !excludesTarget(sourceIDs, targetID) {\n    return nil // drop onto itself: treat as no-op\n}","preventionTips":["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"],"tags":["validation","argument-validation","go"],"backgroundTag":"invalid-argument-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}