siyuan-note/siyuan · error
Please unlock the encrypted notebook first
Error message
Please unlock the encrypted notebook first
What it means
Thrown by RollbackRepoSnapshotFile() via Conf.Language(314) which resolves to 'Please unlock the encrypted notebook first'. When rolling back a .sy file that belongs to an encrypted notebook, the code checks IsEncryptedBox(origBoxID) and Conf.Box(origBoxID). If the notebook is encrypted but not currently mounted (Conf.Box returns nil), rollback is refused because WriteTree would fall back to a non-encrypted box and write decrypted content as plaintext, violating the encryption boundary.
Source
Thrown at kernel/model/repository.go:315
if err = os.WriteFile(from, data, 0644); nil != err {
logging.LogErrorf("write file [%s] failed: %v", filepath.Join(tempRepoDiffDir, file.Path), err)
return
}
// 解密后的临时文件在函数返回时清理,避免加密文档明文残留在磁盘
defer os.Remove(from)
if strings.HasSuffix(file.Path, ".sy") {
boxID := strings.TrimPrefix(file.Path, "/")
boxID = strings.Split(boxID, "/")[0]
origBoxID := boxID // 保留原始 boxID 用于加密边界校验
// 加密笔记本的快照回滚要求原笔记本已挂载:
// WriteTree 根据 tree.Box 判断是否加密落盘。若原笔记本未挂载导致
// getRollbackBox fallback 到普通 Rollback 笔记本,解密后的 .sy 将被 WriteTree
// 以明文落盘,违反加密笔记本"数据不跨边界"的约束。
if IsEncryptedBox(origBoxID) && nil == Conf.Box(origBoxID) {
logging.LogErrorf("rollback encrypted repo snapshot requires notebook [%s] to be mounted", origBoxID)
err = errors.New(Conf.Language(314))
return
}
var box *Box
var needResetTree bool
box, needResetTree, err = getRollbackBox(boxID)
if err != nil {
logging.LogErrorf("get rollback box [%s] failed: %s", boxID, err)
return
}
boxID = box.ID
var destPath, parentHPath string
rootID := util.GetTreeID(file.Path)
workingDoc := treenode.GetBlockTree(rootID)
if needResetTree {
workingDoc = nil
}View on GitHub (pinned to 251596fc0d)
Solutions
- Unlock/mount the encrypted notebook in the SiYuan UI before attempting the rollback.
- In the UI/API layer, check Conf.Box(boxID) != nil for encrypted notebooks before enabling the rollback action.
- After unlocking, retry the rollback operation.
Example fix
// before — encrypted notebook not mounted
err := model.RollbackRepoSnapshotFile(fileID)
// after — unlock the notebook first
box := model.Conf.Box(origBoxID)
if model.IsEncryptedBox(origBoxID) && box == nil {
util.PushMsg("Please unlock the encrypted notebook first", 7000)
return
}
err := model.RollbackRepoSnapshotFile(fileID) Defensive patterns
Strategy: validation
Validate before calling
// For encrypted notebooks, verify the notebook is mounted before rollback
if IsEncryptedBox(boxID) && Conf.Box(boxID) == nil {
return errors.New("please unlock and mount the encrypted notebook before rolling back files")
}
err := model.RollbackRepoSnapshotFile(fileID) Type guard
func isEncryptedBoxMounted(boxID string) bool {
if !IsEncryptedBox(boxID) {
return true // not encrypted, always OK
}
return Conf.Box(boxID) != nil
} Prevention
- Unlock encrypted notebooks before accessing their repo history.
- In the UI, check notebook mount status before enabling rollback for encrypted notebook files.
- Show a clear prompt directing the user to unlock the notebook first.
When it happens
Trigger: Calling RollbackRepoSnapshotFile(fileID) where the file path starts with an encrypted notebook ID, and that notebook is not currently mounted/unlocked (Conf.Box(boxID) returns nil). The encrypted notebook must be mounted so WriteTree can correctly persist the decrypted content back as encrypted.
Common situations: The user locked the encrypted notebook (or it auto-locked) and then tried to roll back a file from the data repo history. The encrypted notebook was never mounted in the current session. The user is browsing repo history from the global view without unlocking the specific encrypted notebook first.
Related errors
- Please initialize the data repo key first in [Settings - Acc
- encrypted notebook is locked, please unlock it first
- refuse to write decrypted asset inside workspace
- source is not an encrypted asset
- CLI does not support encrypted notebook [%s]
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/0f9c2b0f382ef2b3.
Report an issue: GitHub.