siyuan-note/siyuan · error
list encrypted notebooks failed: %w
Error message
list encrypted notebooks failed: %w
What it means
EnableEncryptedNotebook returns a wrapped error at line 991 when hasEncryptedNotebook() fails. This is a precondition scan used to decide whether to recover an existing key domain or generate a fresh MasterSalt; if the scan itself errors, the function cannot safely proceed in either direction and aborts. The underlying error is preserved via %w.
Source
Thrown at kernel/model/crypto.go:991
// KEK 不缓存——启用后用户需对每个加密笔记本单独调 UnlockBox 解锁。
func EnableEncryptedNotebook(password string) error {
if len(password) == 0 {
return errors.New("password must not be empty")
}
notebookCryptoMu.Lock()
defer notebookCryptoMu.Unlock()
Conf.m.RLock()
current := *Conf.NotebookCrypto
Conf.m.RUnlock()
if current.Enabled && notebookCryptoConfigurationComplete(¤t) {
return errors.New(Conf.Language(312))
}
hasEncrypted, listErr := hasEncryptedNotebook()
if listErr != nil {
return fmt.Errorf("list encrypted notebooks failed: %w", listErr)
}
hasHistory, historyErr := scanEncryptedNotebookHistory()
if historyErr != nil {
return fmt.Errorf("check encrypted notebook history failed: %w", historyErr)
}
hasBackup := filelock.IsExist(dataCryptoBackupPath())
if hasEncrypted || hasHistory || hasBackup {
// 现存笔记本、已删除笔记本历史或全局备份均表示已有密钥域,必须恢复并认证,不能生成新 MasterSalt。
kek, restoreErr := tryRestoreNotebookCryptoFromBackupLocked(password)
if kek != nil {
zeroAndClear(kek)
}
if restoreErr != nil {
if strings.Contains(restoreErr.Error(), Conf.Language(311)) {
return errors.New(Conf.Language(311))
}
return errors.New(Conf.Language(315))
}View on GitHub (pinned to 251596fc0d)
Solutions
- Inspect the wrapped error (errors.Unwrap) to identify whether it is blocktree, filesystem, or notebook-metadata related.
- Resolve the underlying storage/index issue (repair permissions, close competing locks, reindex) and retry.
- Do not attempt to bypass the scan by clearing state — that risks generating a new key domain over existing encrypted data.
Defensive patterns
Strategy: try-catch
Try / catch
// Unwrap and route the precondition failure.
if err := model.EnableEncryptedNotebook(password); err != nil {
var unwrapped error
if errors.As(err, &unwrapped) {
log.Printf("notebook scan failed: %v", unwrapped)
}
} Prevention
- Resolve notebook-index/storage issues before attempting to enable encryption.
- Do not bypass the scan by clearing state — doing so risks orphaning existing encrypted notebooks.
- Treat scan failure as fail-closed; retry only after the underlying issue is fixed.
When it happens
Trigger: hasEncryptedNotebook() returns a non-nil error while listing/scanning notebooks for encryption markers. Causes: notebook index/blocktree read failure, filesystem error reading notebook metadata, or a corrupted notebook directory.
Common situations: Workspace with a corrupted .sy metadata file; blocktree.db locked or unreadable; notebook directory permission error; concurrent unmount/mount racing with the scan; storage media degradation.
Related errors
- check encrypted notebook history failed: %w
- prepare box conf [%s] failed: %w
- encrypted notebook key material is missing
- Encrypted notebooks already exist but the master key backup
- save encrypted notebook conf failed: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/c71c2730a2248bcd.
Report an issue: GitHub.