{"record":{"id":"c71c2730a2248bcd","repo":"siyuan-note/siyuan","slug":"list-encrypted-notebooks-failed-w","errorCode":null,"errorMessage":"list encrypted notebooks failed: %w","messagePattern":"list encrypted notebooks failed: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/crypto.go","lineNumber":1013,"sourceCode":"// KEK 不缓存——启用后用户需对每个加密笔记本单独调 UnlockBox 解锁。\nfunc EnableEncryptedNotebook(password string) error {\n\tif len(password) == 0 {\n\t\treturn errors.New(\"password must not be empty\")\n\t}\n\n\tnotebookCryptoMu.Lock()\n\tdefer notebookCryptoMu.Unlock()\n\n\tConf.m.RLock()\n\tcurrent := *Conf.NotebookCrypto\n\tConf.m.RUnlock()\n\tif current.Enabled && notebookCryptoConfigurationComplete(&current) {\n\t\treturn errors.New(Conf.Language(312))\n\t}\n\n\thasEncrypted, listErr := hasEncryptedNotebook()\n\tif listErr != nil {\n\t\treturn fmt.Errorf(\"list encrypted notebooks failed: %w\", listErr)\n\t}\n\thasHistory, historyErr := scanEncryptedNotebookHistory()\n\tif historyErr != nil {\n\t\treturn fmt.Errorf(\"check encrypted notebook history failed: %w\", historyErr)\n\t}\n\thasBackup := filelock.IsExist(dataCryptoBackupPath())\n\tif hasEncrypted || hasHistory || hasBackup {\n\t\t// 现存笔记本、已删除笔记本历史或全局备份均表示已有密钥域，必须恢复并认证，不能生成新 MasterSalt。\n\t\tkek, restoreErr := tryRestoreNotebookCryptoFromBackupLocked(password)\n\t\tif kek != nil {\n\t\t\tzeroAndClear(kek)\n\t\t}\n\t\tif restoreErr != nil {\n\t\t\tif strings.Contains(restoreErr.Error(), Conf.Language(311)) {\n\t\t\t\treturn errors.New(Conf.Language(311))\n\t\t\t}\n\t\t\treturn errors.New(Conf.Language(315))\n\t\t}","sourceCodeStart":995,"sourceCodeEnd":1031,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/crypto.go#L995-L1031","documentation":"Before creating new key material, EnableEncryptedNotebook scans existing notebooks via hasEncryptedNotebook(); if that scan fails the function aborts with fmt.Errorf(\"list encrypted notebooks failed: %w\", listErr). It cannot safely decide whether a key domain already exists, and creating a new MasterSalt in that situation could orphan existing encrypted data.","triggerScenarios":"hasEncryptedNotebook returns an error while EnableEncryptedNotebook (or EnableEncryptedNotebookWithSync) runs — typically the underlying notebook listing/I/O fails: workspace data directory unreadable, .sy file iteration error, or disk/permission problems during the pre-enable scan.","commonSituations":"Running the kernel against a workspace with bad permissions or a corrupted data directory; disk full or I/O errors while enumerating notebooks; tests with an uninitialized workspace path causing the list call to fail.","solutions":["Inspect the wrapped cause (%w) in the error message to find the underlying list failure and fix it (permissions, missing data dir, disk space)","Verify the workspace data directory exists and is readable by the kernel process","Retry after fixing the environment; the scan is read-only and safe to re-run","Do not force-enable encryption while this scan fails — the guard exists to protect existing encrypted data"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := model.EnableEncryptedNotebook(password); err != nil {\n    var wrapped error\n    if strings.Contains(err.Error(), \"list encrypted notebooks failed\") {\n        wrapped = errors.Unwrap(err) // inspect the underlying cause\n    }\n    return fmt.Errorf(\"enable failed: %w\", err)\n}","preventionTips":["Ensure the workspace data directory exists and is writable/readable before enabling","Monitor disk space and permissions in deployment environments","Log errors.Unwrap results to capture root causes","Never bypass the pre-enable scan guard; fix the environment instead"],"tags":["filesystem","notebook-scan","wrapped-error"],"backgroundTag":"file-read-failed","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"}