siyuan-note/siyuan · error
initialize encrypted notebook document failed
Error message
initialize encrypted notebook document failed: %w
What it means
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).
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.
Example fix
// before
id, err := model.UnlockEncryptedBox(id, key)
if err != nil { return err }
// after
id, err := model.UnlockEncryptedBox(id, key)
if err != nil {
logging.LogFatalf("unlock failed: %v", err) // %v prints the wrapped initializeBoxDoc cause
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check notebook dir exists and is writable before unlocking
if _, err := os.Stat(filepath.Join(util.DataDir, boxID)); err != nil {
return fmt.Errorf("notebook data missing: %w", err)
} Try / catch
id, err := model.UnlockEncryptedBox(id, key)
if err != nil {
var root error
for e := err; e != nil; e = errors.Unwrap(e) { root = e }
logging.LogFatalf("unlock/init failed, root cause: %v", root)
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- encrypted attribute view snapshot has no matching notebook
- encrypted notebook key material is missing
- encrypted notebook lock callbacks are not initialized
- Please unlock the encrypted notebook first
- 26
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/d7bb2a2f41b7e019.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/crypto.go:2693
cachedDEKsLock.Unlock()
return "", err
}
if err = treenode.OpenEncryptedBlockTreeDB(id, dek); err != nil {
sql.CloseEncryptedDB(id)
cachedDEKsLock.Unlock()
return "", err
}
cachedDEKs[id] = dek
cachedDEKsLock.Unlock()
// DEK 和加密数据库就绪后允许内部初始化读取密钥,但在笔记本文档创建完成前不接纳外部请求。
newVal := &atomic.Int64{}
newVal.Store(time.Now().UnixNano())
boxLastAccess.Store(id, newVal)
setEncryptedBoxStateWithAdmission(id, EncryptedBoxStateUnlocked, false)
if _, err = initializeBoxDoc(id); err != nil {
return "", fmt.Errorf("initialize encrypted notebook document failed: %w", err)
}
setEncryptedBoxState(id, EncryptedBoxStateUnlocked)
IncSync()
return id, nil
}
// cleanupFailedEncryptedBox 清理创建失败的加密笔记本,清理目标必须是 DataDir 下的有效笔记本目录。
func cleanupFailedEncryptedBox(boxID string) {
if !ast.IsNodeIDPattern(boxID) {
logging.LogErrorf("refuse to cleanup failed encrypted box with invalid ID [%s]", boxID)
return
}
dataDir := filepath.Clean(util.DataDir)
boxDir := filepath.Clean(filepath.Join(dataDir, boxID))
if boxDir == dataDir || filepath.Dir(boxDir) != dataDir {
logging.LogErrorf("refuse to cleanup failed encrypted box outside data directory [%s]", boxDir)View on GitHub (pinned to 8641553a1f)