{"record":{"id":"7f81d3821e33e53a","repo":"siyuan-note/siyuan","slug":"box-document-id-s-does-not-match-box-id-s","errorCode":null,"errorMessage":"box document ID [%s] does not match box ID [%s]","messagePattern":"box document ID \\[(.+?)\\] does not match box ID \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/box_doc.go","lineNumber":80,"sourceCode":"\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\terr = nil\n\t\t}\n\t\treturn\n\t}\n\n\tmeta := &boxDocMeta{}\n\tif err = gulu.JSON.UnmarshalJSON(data, meta); err != nil {\n\t\treturn \"\", fmt.Errorf(\"unmarshal box document metadata failed: %w\", err)\n\t}\n\tif boxDocMetaSpec != meta.Spec {\n\t\treturn \"\", fmt.Errorf(\"unsupported box document metadata spec [%d]\", meta.Spec)\n\t}\n\tif !ast.IsNodeIDPattern(meta.BoxDocID) {\n\t\treturn \"\", fmt.Errorf(\"invalid box document ID [%s]\", meta.BoxDocID)\n\t}\n\tif boxID != meta.BoxDocID {\n\t\treturn \"\", fmt.Errorf(\"box document ID [%s] does not match box ID [%s]\", meta.BoxDocID, boxID)\n\t}\n\treturn boxID, nil\n}\n\nfunc writeBoxDocID(boxID string) error {\n\tmeta := &boxDocMeta{Spec: boxDocMetaSpec, BoxDocID: boxID}\n\tdata, err := gulu.JSON.MarshalIndentJSON(meta, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal box document metadata failed: %w\", err)\n\t}\n\treturn filelock.WriteFile(boxDocMetaPath(boxID), data)\n}\n\nfunc IsBoxDocEnabled() bool {\n\treturn nil != Conf && nil != Conf.FileTree && nil != Conf.FileTree.BoxDocEnabled && *Conf.FileTree.BoxDocEnabled\n}\n\nfunc hiddenBoxDocRootIDs() (ret []string) {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/box_doc.go#L62-L98","documentation":"Thrown by readBoxDocID in kernel/model/box_doc.go when boxDoc.json parses and its boxDocID is a well-formed node ID, but it differs from the box ID derived from the notebook folder that contains the file. A notebook's box document is keyed by that notebook's own ID, so a mismatch means the metadata belongs to a different notebook.","triggerScenarios":"Renaming a notebook's data folder without regenerating boxDoc.json; copying a notebook directory to a new folder name; restoring another workspace's .siyuan metadata into this one; sync applying a boxDoc.json from a snapshot of a differently-IDed notebook.","commonSituations":"Manual workspace surgery or migration; backup/restore into a different workspace; mixed-version sync where one peer wrote meta under an old box ID; copying a notebook via the file manager instead of SiYuan's own duplicate-notebook API.","solutions":["Read the two IDs from the error message: the first is the stored boxDocID, the second is the notebook folder name","Either rename the data folder back to the stored boxDocID, or edit boxDoc.json so boxDocID equals the current folder name","If unsure which is authoritative, delete boxDoc.json and let EnsureBoxDoc regenerate it from the existing hidden /<boxID>.sy document","Re-run the failed mount/sync operation"],"exampleFix":"// before: data/20240601120000-newbox01/.siyuan/boxDoc.json\n{\"spec\":1,\"boxDocID\":\"20230101130405-oldbox1\"}\n// after\n{\"spec\":1,\"boxDocID\":\"20240601120000-newbox01\"}","handlingStrategy":"try-catch","validationCode":"// read the meta and compare before triggering the failing path\ndata, err := os.ReadFile(filepath.Join(dataDir, boxID, \".siyuan\", \"boxDoc.json\"))\nif err == nil {\n\tvar m struct {\n\t\tSpec     int    `json:\"spec\"`\n\t\tBoxDocID string `json:\"boxDocID\"`\n\t}\n\t_ = json.Unmarshal(data, &m)\n\tif m.BoxDocID != \"\" && m.BoxDocID != boxID {\n\t\t// fix or delete the file before calling EnsureBoxDoc\n\t}\n}","typeGuard":null,"tryCatchPattern":"if _, err := model.EnsureBoxDoc(boxID); err != nil {\n\tif strings.Contains(err.Error(), \"does not match box ID\") {\n\t\t// metadata belongs to another notebook: rename folder back or delete boxDoc.json\n\t}\n\treturn err\n}","preventionTips":["Rename/duplicate notebooks only through SiYuan APIs so boxDoc.json follows","Never copy .siyuan metadata between notebook folders manually","After workspace restores, open every notebook once and check kernel logs"],"tags":["siyuan","box-doc","notebook","metadata","id-mismatch"],"backgroundTag":"metadata-id-mismatch","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}