{"record":{"id":"d7bb2a2f41b7e019","repo":"siyuan-note/siyuan","slug":"initialize-encrypted-notebook-document-failed-w","errorCode":null,"errorMessage":"initialize encrypted notebook document failed: %w","messagePattern":"initialize encrypted notebook document failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":2693,"sourceCode":"\t\tcachedDEKsLock.Unlock()\n\t\treturn \"\", err\n\t}\n\tif err = treenode.OpenEncryptedBlockTreeDB(id, dek); err != nil {\n\t\tsql.CloseEncryptedDB(id)\n\t\tcachedDEKsLock.Unlock()\n\t\treturn \"\", err\n\t}\n\tcachedDEKs[id] = dek\n\tcachedDEKsLock.Unlock()\n\n\t// DEK 和加密数据库就绪后允许内部初始化读取密钥，但在笔记本文档创建完成前不接纳外部请求。\n\tnewVal := &atomic.Int64{}\n\tnewVal.Store(time.Now().UnixNano())\n\tboxLastAccess.Store(id, newVal)\n\tsetEncryptedBoxStateWithAdmission(id, EncryptedBoxStateUnlocked, false)\n\n\tif _, err = initializeBoxDoc(id); err != nil {\n\t\treturn \"\", fmt.Errorf(\"initialize encrypted notebook document failed: %w\", err)\n\t}\n\n\tsetEncryptedBoxState(id, EncryptedBoxStateUnlocked)\n\tIncSync()\n\treturn id, nil\n}\n\n// cleanupFailedEncryptedBox 清理创建失败的加密笔记本，清理目标必须是 DataDir 下的有效笔记本目录。\nfunc cleanupFailedEncryptedBox(boxID string) {\n\tif !ast.IsNodeIDPattern(boxID) {\n\t\tlogging.LogErrorf(\"refuse to cleanup failed encrypted box with invalid ID [%s]\", boxID)\n\t\treturn\n\t}\n\n\tdataDir := filepath.Clean(util.DataDir)\n\tboxDir := filepath.Clean(filepath.Join(dataDir, boxID))\n\tif boxDir == dataDir || filepath.Dir(boxDir) != dataDir {\n\t\tlogging.LogErrorf(\"refuse to cleanup failed encrypted box outside data directory [%s]\", boxDir)","sourceCodeStart":2675,"sourceCodeEnd":2711,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/crypto.go#L2675-L2711","documentation":"This error wraps a failure that occurred while initializing the document structure of an encrypted notebook after it was successfully unlocked. The unlock itself succeeded (the box state was set to unlocked with admission), but `initializeBoxDoc(id)` failed, so the whole unlock operation is aborted by wrapping the underlying cause with `%w`. Callers should inspect the wrapped error to learn the real failure reason (e.g. I/O or tree-format problems).","triggerScenarios":"Calling the unlock API for an encrypted notebook where `initializeBoxDoc` returns an error — e.g. the box's root `.sy` document cannot be created or parsed after decryption.","commonSituations":"Corrupted notebook data directory after an interrupted sync or crash; a notebook whose documents were written by an incompatible version; disk-full or permission errors preventing creation of the initial document.","solutions":["Inspect the wrapped cause with errors.Unwrap / %v of the returned error to find the real failure (I/O, parse, permission).","Verify the notebook data directory exists and is readable/writable by the SiYuan process.","Rebuild the notebook index or restore the notebook from a backup/sync snapshot if the document tree is corrupted.","Check available disk space and file locks on the workspace directory."],"exampleFix":"// before\nid, err := model.UnlockEncryptedBox(id, key)\nif err != nil { return err }\n// after\nid, err := model.UnlockEncryptedBox(id, key)\nif err != nil {\n    logging.LogFatalf(\"unlock failed: %v\", err) // %v prints the wrapped initializeBoxDoc cause\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// Go: check notebook dir exists and is writable before unlocking\nif _, err := os.Stat(filepath.Join(util.DataDir, boxID)); err != nil {\n    return fmt.Errorf(\"notebook data missing: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"id, err := model.UnlockEncryptedBox(id, key)\nif err != nil {\n    var root error\n    for e := err; e != nil; e = errors.Unwrap(e) { root = e }\n    logging.LogFatalf(\"unlock/init failed, root cause: %v\", root)\n    return err\n}","preventionTips":["Keep the workspace disk from filling up; monitor free space.","Never interrupt the kernel during first unlock/index of a notebook.","Restore corrupted notebooks from sync/backup snapshots rather than hand-editing .sy files."],"tags":["go","encryption","notebook","initialization"],"backgroundTag":"internal-invariant-violation","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}