siyuan-note/siyuan · error
Please unlock the encrypted notebook first
Error message
Please unlock the encrypted notebook first
What it means
Returned by the withExportReadLockByBlockID guard when the target block belongs to an encrypted notebook whose DEK (data-encryption-key) session is not currently unlocked. The guard is the entry checkpoint for every block-level export (Export2Liandi, ExportPreview, ExportDocx, ExportMarkdownHTML, etc.): it refuses to run fn() so that no ciphertext or empty result is read out. Message text is Conf.Language(314).
Source
Thrown at kernel/model/export.go:583
// 用于文档级导出入口的统一 guard,避免未解锁时读出密文或空结果。
func exportLockedByBlockID(id string) bool {
bt := getExportBlockTree(id)
if nil == bt {
return false // 找不到块树,交给后续流程处理
}
return IsEncryptedBox(bt.BoxID) && !IsBoxUnlocked(bt.BoxID)
}
// withExportReadLockByBlockID 由 blockID 反查 boxID,若属于加密笔记本则全程持读锁执行 fn。
// 持锁期间 LockBox(自动锁定)会阻塞等待,避免操作中途清 DEK/删导出目录导致部分明文写出。
// 普通笔记本或块树不存在时直接执行 fn。嵌套调用安全:sync.RWMutex.RLock 可重入。
func withExportReadLockByBlockID(id string, fn func() error) error {
bt := getExportBlockTree(id)
if nil == bt || !IsEncryptedBox(bt.BoxID) {
return fn()
}
if !IsBoxUnlocked(bt.BoxID) {
return errors.New(Conf.Language(314))
}
HoldBoxReadLock(bt.BoxID)
defer ReleaseBoxReadLock(bt.BoxID)
if _, dekErr := GetDEKIfUnlocked(bt.BoxID); dekErr != nil {
return errors.New(Conf.Language(314))
}
return fn()
}
func ExportNotebookSY(id string) (zipPath string) {
// 加密笔记本必须已解锁才能导出(DEK 在内存才能读 .sy/assets/AV 明文)
if IsEncryptedBox(id) && !IsBoxUnlocked(id) {
logging.LogErrorf("export encrypted notebook [%s] failed: locked", id)
return
}
zipPath = exportBoxSYZip(id)
return
}View on GitHub (pinned to 251596fc0d)
Solutions
- Unlock the encrypted notebook via the UI (enter the passphrase) before exporting.
- If scripting, call the unlock API first and confirm it succeeds before issuing the export call.
- Increase or disable the auto-lock timeout if exports are long-running and repeatedly get interrupted.
- If exporting via a headless/automated flow, ensure the notebook is unlocked in the same kernel session and process (DEK is not persisted).
Example fix
// before — export called on a still-locked encrypted box
model.ExportDocx(id, savePath, false, false)
// after — unlock first, then export
if model.IsEncryptedBox(boxID) && !model.IsBoxUnlocked(boxID) {
return errors.New("unlock the notebook before exporting")
}
model.ExportDocx(id, savePath, false, false) Defensive patterns
Strategy: validation
Validate before calling
// Validate unlock state before calling any export that routes through withExportReadLockByBlockID
bt := getExportBlockTree(id)
if bt != nil && IsEncryptedBox(bt.BoxID) && !IsBoxUnlocked(bt.BoxID) {
return errors.New(Conf.Language(314)) // prompt user to unlock
} Type guard
// isExportableEncryptedBlock reports whether id is in an encrypted box that is currently unlocked.
func isExportableEncryptedBlock(id string) bool {
bt := getExportBlockTree(id)
if bt == nil || !IsEncryptedBox(bt.BoxID) {
return true // normal boxes are always exportable
}
return IsBoxUnlocked(bt.BoxID)
} Try / catch
if err := model.ExportDocx(id, savePath, false, false); err != nil {
if err.Error() == Conf.Language(314) {
// prompt: unlock the encrypted notebook and retry
}
} Prevention
- Unlock encrypted notebooks before invoking any export API.
- In automated flows, call unlock and verify IsBoxUnlocked before exporting.
- Surface the unlock requirement to the user UI before they click export.
When it happens
Trigger: Calling any export API whose id resolves to a block in an encrypted notebook while the notebook is locked — i.e. the user has not entered the passphrase, the session expired, or the kernel was restarted (DEK is in-memory only). Also hit if LockBox auto-locked the notebook between the UI action and the API call.
Common situations: User scheduled an export or a plugin automated an export against an encrypted notebook without first unlocking it. Kernel restart cleared the in-memory DEK. Auto-lock timeout fired during a long batch.
Related errors
- Please unlock the encrypted notebook first
- Cannot import a key backup while encrypted notebooks are ena
- 312
- encrypted notebook is locked, please unlock it first
- exporting non-asset files from encrypted notebooks is not su
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/fb6dee2082d3a021.
Report an issue: GitHub.