{"record":{"id":"1948abdb2988057e","repo":"siyuan-note/siyuan","slug":"box-document-id-s-is-already-in-use","errorCode":null,"errorMessage":"box document ID [%s] is already in use","messagePattern":"box document ID \\[(.+?)\\] is already in use","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/box_doc.go","lineNumber":151,"sourceCode":"\tbox := Conf.GetBox(boxID)\n\tif nil == box {\n\t\treturn \"\", ErrBoxNotFound\n\t}\n\n\tif !IsBoxDocEnabled() {\n\t\treturn\n\t}\n\tboxDocID = boxID\n\n\tboxDocID, err = findBoxDoc(box)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tcreated, changed := false, false\n\tif \"\" == boxDocID {\n\t\tboxDocID = boxID\n\t\tif box.Exist(boxDocPath(boxDocID)) || nil != treenode.GetBlockTree(boxDocID) || \"\" != findUnindexedTreePathInAllBoxes(boxDocID) {\n\t\t\treturn \"\", fmt.Errorf(\"box document ID [%s] is already in use\", boxDocID)\n\t\t}\n\t\tif err = createBoxDoc(box, boxDocID); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tcreated = true\n\t\tchanged = true\n\t} else {\n\t\tindexBoxDocIfNeeded(boxID, boxDocID)\n\t\tif err = reconcileBoxDoc(box, boxDocID); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\tstoredBoxDocID, _ := readBoxDocID(boxID)\n\tif storedBoxDocID != boxID {\n\t\tif err = writeBoxDocID(boxID); err != nil {\n\t\t\treturn \"\", err\n\t\t}","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/box_doc.go#L133-L169","documentation":"When the box-doc feature is enabled and a notebook has no box document yet, ensureBoxDoc0 (kernel/model/box_doc.go:151) tries to create the hidden doc at /<boxID>.sy with root ID equal to the box ID. Creation is refused if that file already exists on disk, a block tree with that ID is already indexed (treenode.GetBlockTree), or any unindexed tree in any notebook carries that root ID (findUnindexedTreePathInAllBoxes). Block IDs are globally unique in a workspace, so the box doc ID cannot collide with real content.","triggerScenarios":"Enabling the box-doc feature on a workspace where some document's ID happens to equal a notebook ID (typical after import, migration, or manual .sy tampering); a leftover partial /<boxID>.sy file; the index still holding a stale entry for that ID.","commonSituations":"Feature toggled on after the workspace existed for a long time; data imported from another workspace preserving IDs; an earlier box-doc creation interrupted halfway, leaving the .sy file but no boxDoc.json; index not rebuilt after manual file operations.","solutions":["Run an index rebuild (or /api/filetree/refreshFiletree) to clear stale index entries, then retry","Search the colliding ID via SQL (select * from blocks where id = '<boxID>') to locate the occupying document","If the occupying doc is junk or a leftover, delete it (and its /<boxID>.sy file), then retry","If it is real content, change that block's ID or move the content, then re-enable the box doc feature"],"exampleFix":"// SQL to locate the colliding block before retrying EnsureBoxDoc\nSELECT id, box, path, content FROM blocks WHERE id = '20230101130405-oldbox1';\n// after resolving (delete/rename), the same call succeeds\nboxDocID, err := model.EnsureBoxDoc(boxID)","handlingStrategy":"try-catch","validationCode":"// pre-flight the three occupation checks the kernel performs\noccupied := box.Exist(\"/\" + boxID + \".sy\") ||\n\ttreenode.GetBlockTree(boxID) != nil ||\n\tfindUnindexedTreePathInAllBoxes(boxID) != \"\"\nif occupied {\n\t// resolve the collision before enabling the box-doc feature\n}","typeGuard":null,"tryCatchPattern":"if _, err := model.EnsureBoxDoc(boxID); err != nil {\n\tif strings.Contains(err.Error(), \"already in use\") {\n\t\t// rebuild index; locate and move/re-ID the colliding doc; retry once\n\t}\n\treturn err\n}","preventionTips":["Rebuild the index after bulk file operations before enabling the box-doc feature","Avoid importing raw .sy trees that preserve IDs clashing with notebook IDs","When enabling the feature workspace-wide, refreshFiletree first"],"tags":["siyuan","box-doc","notebook","id-collision","data-integrity"],"backgroundTag":"identifier-collision","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}