{"record":{"id":"8486b50ca0eb781c","repo":"siyuan-note/siyuan","slug":"source-id-s-is-not-in-the-current-order","errorCode":null,"errorMessage":"source ID [%s] is not in the current order","messagePattern":"source ID \\[(.+?)\\] is not in the current order","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":2793,"sourceCode":"\t}\n\treturn mergeRequestedIDOrder(currentIDs, requestedIDs)\n}\n\nfunc reorderIDSequence(currentIDs, sourceIDs []string, targetID, position string) (ret []string, changed bool, err error) {\n\tif err = validateReorderArgs(sourceIDs, targetID, position); nil != err {\n\t\treturn\n\t}\n\tcurrentSet := make(map[string]struct{}, len(currentIDs))\n\tfor _, id := range currentIDs {\n\t\tcurrentSet[id] = struct{}{}\n\t}\n\tif _, exists := currentSet[targetID]; !exists {\n\t\treturn nil, false, fmt.Errorf(\"target ID [%s] is not in the current order\", targetID)\n\t}\n\tsourceSet := make(map[string]struct{}, len(sourceIDs))\n\tfor _, sourceID := range sourceIDs {\n\t\tif _, exists := currentSet[sourceID]; !exists {\n\t\t\treturn nil, false, fmt.Errorf(\"source ID [%s] is not in the current order\", sourceID)\n\t\t}\n\t\tsourceSet[sourceID] = struct{}{}\n\t}\n\tremaining := make([]string, 0, len(currentIDs)-len(sourceIDs))\n\tfor _, id := range currentIDs {\n\t\tif _, source := sourceSet[id]; !source {\n\t\t\tremaining = append(remaining, id)\n\t\t}\n\t}\n\ttargetIndex := -1\n\tfor i, id := range remaining {\n\t\tif id == targetID {\n\t\t\ttargetIndex = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif \"after\" == position {\n\t\ttargetIndex++","sourceCodeStart":2775,"sourceCodeEnd":2811,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/file.go#L2775-L2811","documentation":"reorderIDSequence validates each source ID being moved against the set of currently known IDs in the sort sequence. If any sourceID is not present in the current order, the whole reorder is rejected with this error and the sequence is left untouched.","triggerScenarios":"Passing one or more sourceIDs (docs/notebooks being dragged) that are absent from currentIDs in the file-tree reorder API — e.g. IDs of items deleted concurrently, IDs belonging to another notebook/parent, or duplicated/stale selections from the UI.","commonSituations":"Multi-select drag where one selected document was deleted by sync between selection and drop; client caches IDs across a rename/copy; caller accidentally passes a target block ID (heading/child block) rather than the document root ID of the .sy file.","solutions":["Reload the current children list of the parent folder and filter the request's sourceIDs down to those actually present before calling the reorder.","Confirm each source ID is a document root ID (matches the .sy filename) in the same notebook and parent directory.","Remove deleted/nonexistent IDs from the request and retry with the remaining valid ones.","Refresh the file tree in the client so selection state matches the server-side state."],"exampleFix":"// before\nsources := uiSelection // may contain stale IDs\nreorder(parentPath, sources, target, \"after\")\n// after\ncurrent := loadCurrentOrder(parentPath)\nsources = filterIn(current, uiSelection)\nreorder(parentPath, sources, target, \"after\")","handlingStrategy":"validation","validationCode":"const current = new Set(await loadSortOrder(parentPath));\nconst valid = sourceIDs.filter(id => current.has(id));\nif (valid.length !== sourceIDs.length) {\n  console.warn(\"dropping stale source IDs\", sourceIDs.filter(id => !current.has(id)));\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.setFileTreeSort(payload);\n} catch (e) {\n  if (String(e).includes(\"source ID\") && String(e).includes(\"not in the current order\")) {\n    const fresh = await loadSortOrder(parentPath);\n    payload.sourceIDs = payload.sourceIDs.filter(id => fresh.includes(id));\n    return api.setFileTreeSort(payload);\n  }\n  throw e;\n}","preventionTips":["Filter multi-select selections against a freshly fetched sibling list before dragging","Validate that every source ID corresponds to a .sy file name in the target parent","Refresh tree state after sync/delete events so selections cannot go stale"],"tags":["file-tree","sort","validation","stale-id"],"backgroundTag":"resource-not-found","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"}