{"record":{"id":"4255b57f199fe9e0","repo":"siyuan-note/siyuan","slug":"sort-target-document-s-not-found","errorCode":null,"errorMessage":"sort target document [%s] not found","messagePattern":"sort target document \\[(.+?)\\] not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":3100,"sourceCode":"\t}\n\tinsertIndex := 0\n\tif \"after\" == position {\n\t\tinsertIndex = len(orderedIDs)\n\t}\n\tif \"\" != targetID {\n\t\tinsertIndex = -1\n\t\tfor i, currentID := range orderedIDs {\n\t\t\tif currentID == targetID {\n\t\t\t\tinsertIndex = i\n\t\t\t\tif \"after\" == position {\n\t\t\t\t\tinsertIndex++\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif 0 > insertIndex {\n\t\t\tfileTreeSortLock.Unlock()\n\t\t\treturn fmt.Errorf(\"sort target document [%s] not found\", targetID)\n\t\t}\n\t}\n\torderedIDs = append(orderedIDs, \"\")\n\tcopy(orderedIDs[insertIndex+1:], orderedIDs[insertIndex:])\n\torderedIDs[insertIndex] = id\n\tsortIDs := make(map[string]int, len(orderedIDs))\n\tfor i, orderedID := range orderedIDs {\n\t\tsortIDs[orderedID] = i + 1\n\t}\n\tmaps.Copy(fullSortIDs, sortIDs)\n\tif err = writeSortConfMap(confPath, fullSortIDs); nil != err {\n\t\tfileTreeSortLock.Unlock()\n\t\treturn err\n\t}\n\tfileTreeSortLock.Unlock()\n\tpushFiletreeSortChanged(sortIDs)\n\treturn nil\n}","sourceCodeStart":3082,"sourceCodeEnd":3118,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/file.go#L3082-L3118","documentation":"While applying a custom sibling order, the kernel searches the ordered list of sibling document IDs for the target document (targetID) that defines the insertion position. If the target cannot be found in the parent's child list, the sort is aborted and this error is returned. It indicates the requested sort target no longer exists in that parent (it was removed, moved, or the ID is wrong).","triggerScenarios":"Calling the sibling-order placement API (placeDocInSiblingOrder) with a targetID of a document that is not a current child of the parent path: target was deleted or moved to another notebook/folder before the sort call, the client passed a stale block ID (e.g. cached drag target), or a truncated/invalid ID was supplied.","commonSituations":"Stale frontend state after another session or a sync operation removed/moved the drag target; API/script callers using an old doc ID after reorganizing the tree; concurrent deletion racing a sort request.","solutions":["Refresh the doc tree (GET /api/filetree/listDocsByPath) and retry with a current target document ID","Confirm the target document still exists: POST /api/filetree/getDoc with the ID","Check sync/conflict history — if the target was deleted, remove it from the pending sort request","Re-open the notebook so the in-memory tree and block index are rebuilt","Retry after other devices finish syncing so IDs are no longer stale"],"exampleFix":"// before (stale targetID from cached UI state)\nawait fetchPost('/api/filetree/moveDocs', {targetID: staleTargetID, ...});\n// after (verify target exists first)\nconst resp = await fetchPost('/api/filetree/getDocInfo', {id: targetID});\nif (!resp.data) {\n  const tree = await fetchPost('/api/filetree/listDocsByPath', {notebook: boxID, path: parentPath});\n  targetID = tree.data.files[0].id; // pick a live target\n}\nawait fetchPost('/api/filetree/moveDocs', {targetID, ...});","handlingStrategy":"validation","validationCode":"async function targetExists(boxId, parentPath, targetId) {\n  const r = await fetchPost('/api/filetree/listDocsByPath', {notebook: boxId, path: parentPath});\n  return r.data.files.some(f => f.id === targetId);\n}","typeGuard":"function isBlockId(v) { return typeof v === 'string' && /^[0-9]{14}-[a-z0-9]{7}$/.test(v); }","tryCatchPattern":"try {\n  await sortDocs(parentId, dragIds, targetId);\n} catch (e) {\n  if (String(e).includes('sort target document')) {\n    await refreshFiletree(); // reload tree and retry with a live target\n  }\n}","preventionTips":["Always re-fetch the current doc list before programmatic sort/move calls","Never cache target block IDs across sync cycles or long-running sessions","Handle concurrent deletions: treat a missing target as a retry-after-refresh condition","Verify IDs against getDoc/listDocsByPath before invoking sort APIs"],"tags":["document","not-found","sorting","stale-id"],"backgroundTag":"record-not-found","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}