siyuan-note/siyuan · error

check encrypted notebook history failed

Error message

check encrypted notebook history failed: %w

What it means

During pre-enable checks, EnableEncryptedNotebook calls scanEncryptedNotebookHistory() to detect deleted-notebook history that indicates a prior key domain; if that scan errors the function returns fmt.Errorf("check encrypted notebook history failed: %w", historyErr). Skipping the check could let a new MasterSalt overwrite a key domain still recoverable from history or the global backup.

Solutions

  1. Inspect the wrapped cause (%w) for the underlying history-scan error and repair it (restore history.db from backup, fix permissions, free disk space)
  2. Check the integrity of history.db (SQLite integrity check) and rebuild history indexes if corrupt
  3. Retry after the environment is fixed; the scan is read-only
  4. If a prior key domain is later detected, use the recovery-from-backup path instead of generating fresh key material
Defensive patterns

Strategy: try-catch

Try / catch

if err := model.EnableEncryptedNotebook(password); err != nil {
    if strings.Contains(err.Error(), "check encrypted notebook history failed") {
        // inspect errors.Unwrap(err) for the history.db cause
    }
    return err
}

Prevention

When it happens

Trigger: scanEncryptedNotebookHistory fails while EnableEncryptedNotebook (or EnableEncryptedNotebookWithSync) runs — usually history.db is unreadable/corrupt, the history directory has bad permissions, or an I/O error occurs during the scan.

Common situations: Corrupted or locked history.db in the workspace; partial restore or interrupted sync leaving history in a bad state; running without read permission on the history storage path; tests with a broken/missing history fixture.

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/c720a3e19693819e. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:1017

	}

	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))
		}
		logging.LogInfof("encrypted notebook re-enabled with authenticated recovery key material")
		return nil
	}

View on GitHub (pinned to 9f775e8a12)