siyuan-note/siyuan · error
target document [ ] not found
Error message
target document [%s] not found
What it means
During document sort/reorder operations, the kernel resolves the target document via treenode.GetBlockTree and requires it to be a sortable document (an existing document block). If the target ID does not resolve to a valid document, the operation reports 'target document not found'. Note this message is also reused when the target exists but is not a sortable document, so it covers both missing and ineligible targets.
Solutions
- Re-fetch the document tree/notebook listing and confirm the targetID exists as a document
- Refresh the frontend view so the reorder operation uses current IDs, then retry
- Check the ID is a document (root block) ID, not a child block ID
- If the notebook was recently synced, wait for indexing to complete before reordering
Example fix
// before
reorderDocs(srcIDs, possiblyDeletedID, "after")
// after
if docExists(possiblyDeletedID) {
reorderDocs(srcIDs, possiblyDeletedID, "after")
} Defensive patterns
Strategy: validation
Validate before calling
const target = await getDocTreeItem(targetID)
if (!target || target.type !== "document") throw new Error("target document missing, refresh tree") Type guard
const isDoc = (item) => !!item && item.type === "document"
Try / catch
try { await api.reorderDocs(src, targetID, pos) } catch (e) { if (String(e).includes("target document") && String(e).includes("not found")) { await refreshFileTree(); return retryOnce() } throw e } Prevention
- Refresh the file tree after sync/delete events before issuing reorders
- Never persist document IDs across long-lived jobs without revalidation
- Distinguish document IDs from child block IDs at extraction time
When it happens
Trigger: Calling the doc sort/reorder API with a targetID of a non-existent document, a deleted document, or a non-document block; race where the document was deleted between UI listing and the reorder call.
Common situations: Stale UI state after another client deleted the document via sync; plugins caching document IDs across notebook rebuilds; typos or truncated IDs in manual API scripts.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- source document [ ] not found
- block [ ] is not a document
- block [ ] is not a document that can declare a child…
- boot appearance not found
- ErrBlockNotFound
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/39e10de329cdb2d6.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/file.go:2688
// ReorderResult 描述相对排序操作的结果。
type ReorderResult struct {
Changed bool `json:"changed"`
Notebook string `json:"notebook,omitempty"`
ParentPath string `json:"parentPath,omitempty"`
}
// ReorderDocs 将同级文档移动到目标文档之前或之后。
func ReorderDocs(sourceIDs []string, targetID, position string) (ret *ReorderResult, err error) {
ret = &ReorderResult{}
if err = validateReorderArgs(sourceIDs, targetID, position); nil != err {
return
}
FlushTxQueue()
target := treenode.GetBlockTree(targetID)
if !isSortableDocument(target) {
return ret, fmt.Errorf("target document [%s] not found", targetID)
}
box := Conf.Box(target.BoxID)
if nil == box {
return ret, fmt.Errorf("target document [%s] is not in an opened and unlocked notebook", targetID)
}
parentPath := path.Dir(target.Path)
for _, sourceID := range sourceIDs {
source := treenode.GetBlockTree(sourceID)
if !isSortableDocument(source) {
return ret, fmt.Errorf("source document [%s] not found", sourceID)
}
if source.BoxID != target.BoxID || path.Dir(source.Path) != parentPath {
return ret, fmt.Errorf("source document [%s] is not a sibling of target document [%s]", sourceID, targetID)
}
}
fileTreeSortLock.Lock()
confPath := filepath.Join(util.DataDir, box.ID, ".siyuan", "sort.json")View on GitHub (pinned to 9f775e8a12)