siyuan-note/siyuan · error

list encrypted notebooks failed

Error message

list encrypted notebooks failed: %w

What it means

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.

Solutions

  1. Inspect the wrapped cause (%w) in the error message to find the underlying list failure and fix it (permissions, missing data dir, disk space)
  2. Verify the workspace data directory exists and is readable by the kernel process
  3. Retry after fixing the environment; the scan is read-only and safe to re-run
  4. Do not force-enable encryption while this scan fails — the guard exists to protect existing encrypted data
Defensive patterns

Strategy: try-catch

Try / catch

if err := model.EnableEncryptedNotebook(password); err != nil {
    var wrapped error
    if strings.Contains(err.Error(), "list encrypted notebooks failed") {
        wrapped = errors.Unwrap(err) // inspect the underlying cause
    }
    return fmt.Errorf("enable failed: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/c71c2730a2248bcd. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:1013

// 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(&current) {
		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 9f775e8a12)