{"record":{"id":"38f990aff4837613","repo":"siyuan-note/siyuan","slug":"block-s-is-not-a-document-that-can-declare-a-ch","errorCode":null,"errorMessage":"block [%s] is not a document that can declare a child document sort mode","messagePattern":"block \\[(.+?)\\] is not a document that can declare a child document sort mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":2509,"sourceCode":"\tID                string `json:\"id\"`\n\tPath              string `json:\"path\"`\n\tSortMode          *int   `json:\"sortMode\"`\n\tEffectiveSortMode int    `json:\"effectiveSortMode\"`\n}\n\n// SetDocSortMode 设置文档对子文档列表声明的排序方式，sortMode 为 nil 时恢复继承。\nfunc SetDocSortMode(id string, sortMode *int) (ret *DocSortModeResult, err error) {\n\tif nil != sortMode && !IsValidDocSortMode(*sortMode) {\n\t\treturn nil, fmt.Errorf(\"invalid document sort mode [%d]\", *sortMode)\n\t}\n\n\tFlushTxQueue()\n\ttree, err := LoadTreeByBlockID(id)\n\tif nil != err {\n\t\treturn nil, err\n\t}\n\tif tree.ID != id || tree.Root.ID != id || ast.NodeDocument != tree.Root.Type || IsBoxDoc(tree.Box, tree.ID) {\n\t\treturn nil, fmt.Errorf(\"block [%s] is not a document that can declare a child document sort mode\", id)\n\t}\n\n\tvalue := \"\"\n\tif nil != sortMode {\n\t\tvalue = strconv.Itoa(*sortMode)\n\t}\n\tif tree.Root.IALAttr(DocSortModeAttr) != value {\n\t\tif err = setNodeAttrs(tree.Root, tree, map[string]string{DocSortModeAttr: value}); nil != err {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\teffectiveSortMode, resolveErr := ResolveDocTreeSortMode(tree.Box, tree.Path)\n\tif nil != resolveErr {\n\t\treturn nil, resolveErr\n\t}\n\tret = &DocSortModeResult{\n\t\tBox:               tree.Box,","sourceCodeStart":2491,"sourceCodeEnd":2527,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/file.go#L2491-L2527","documentation":"SetDocSortMode only works on blocks that ARE documents (the tree root, of type NodeDocument) and that live in an opened, non-closed notebook (IsBoxDoc). If the given id does not resolve to such a document, this error is thrown. It guards the document-level sort declaration feature against being applied to ordinary blocks or closed notebooks.","triggerScenarios":"Calling SetDocSortMode with the ID of a heading, paragraph, or child block; passing a document ID whose notebook is closed; passing an ID that does not exist at all (LoadTree succeeds but tree.ID/tree.Root.ID mismatch checks fail).","commonSituations":"Plugins grabbing the wrong selected node ID (e.g. inner block instead of the doc); notebooks closed/unloaded after a workspace switch; IDs copied from search results pointing at non-document blocks.","solutions":["Verify the ID is a document ID (load the .sy tree and check the root node type is NodeDocument) before calling","Check that the notebook containing the document is open in the workspace (not in the closed notebooks list)","Re-resolve the ID from the UI/API tree listing rather than a stale cached value","If targeting a non-document block, remove the call — sort mode can only be declared on documents"],"exampleFix":"// before\nSetDocSortMode(blockID, intPtr(mode)) // blockID may be a child block\n// after\nif docID, ok := resolveDocumentID(blockID); ok {\n    SetDocSortMode(docID, intPtr(mode))\n}","handlingStrategy":"validation","validationCode":"const doc = await getDocTreeItem(id)\nif (!doc || doc.type !== \"document\" || !isNotebookOpen(doc.notebookId)) throw new Error(\"not a document in an open notebook\")","typeGuard":"const isDocumentBlock = (b) => !!b && b.type === \"NodeDocument\" && b.rootId === b.id","tryCatchPattern":"try { await api.setDocSortMode(id, mode) } catch (e) { if (String(e).includes(\"is not a document\")) { /* re-resolve the doc ID from the tree */ } else throw e }","preventionTips":["Resolve document IDs from the file-tree listing API, not from arbitrary block selections","Re-check notebook open state after workspace switches","Cache document IDs only with a freshness policy tied to sync events"],"tags":["go","kernel","document","validation"],"backgroundTag":"entity-not-found","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}