siyuan-note/siyuan · error
Please unlock the encrypted notebook first
Error message
Please unlock the encrypted notebook first
What it means
Thrown by writeImportedTree when the target notebook is encrypted but not currently unlocked. The function calls GetDEKIfUnlocked(boxID) to retrieve the Data Encryption Key (DEK) needed to encrypt the imported tree before writing it to disk. If the notebook is locked (no DEK cached, or the box is not in an unlocked state), the DEK retrieval fails and the write is aborted. The error message uses language code 314.
Source
Thrown at kernel/model/import.go:1019
if err = filelock.Copy(assetsDir, dataAssets); err != nil {
logging.LogErrorf("copy assets from [%s] to [%s] failed: %s", assetsDir, dataAssets, err)
return nil, err
}
if removeErr := os.RemoveAll(assetsDir); removeErr != nil {
return nil, removeErr
}
}
return assetPathMap, nil
}
func writeImportedTree(boxID, syPath, newSyPath, relPath string, data []byte) error {
if IsEncryptedBox(boxID) {
HoldBoxReadLock(boxID)
defer ReleaseBoxReadLock(boxID)
dek, err := GetDEKIfUnlocked(boxID)
if err != nil {
return errors.New(Conf.Language(314))
}
data, err = EncryptFile(boxID, relPath, dek, data)
if err != nil {
return err
}
}
if err := os.WriteFile(syPath, data, 0644); err != nil {
return err
}
return filelock.Rename(syPath, newSyPath)
}
func validateImportedNotebookIdentities(tmpDataPath string) ([]string, error) {
dirs, err := os.ReadDir(tmpDataPath)
if err != nil {
return nil, err
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Unlock the encrypted notebook before importing: call the unlock API or enter the master password in the UI.
- Verify the notebook is in the unlocked state by checking IsEncryptedBox and isBoxUnlockedForAccess before calling import functions.
- If importing via API, ensure the unlock endpoint is called first and the session/token maintains the unlocked state.
- Import into a non-encrypted notebook if the encrypted one cannot be unlocked (e.g., master password forgotten).
Example fix
// before: import without checking unlock state
err := writeImportedTree(boxID, syPath, newSyPath, relPath, data)
// after: verify unlocked state before writing
if model.IsEncryptedBox(boxID) {
if _, err := model.GetDEKIfUnlocked(boxID); err != nil {
return fmt.Errorf("notebook %s must be unlocked before import", boxID)
}
}
err := writeImportedTree(boxID, syPath, newSyPath, relPath, data) Defensive patterns
Strategy: validation
Validate before calling
// Before importing into an encrypted notebook, verify it is unlocked
func ensureBoxUnlocked(boxID string) error {
if !model.IsEncryptedBox(boxID) {
return nil // not encrypted, no check needed
}
if _, err := model.GetDEKIfUnlocked(boxID); err != nil {
return fmt.Errorf("encrypted notebook %s must be unlocked before import: %w", boxID, err)
}
return nil
}
// Call before any import function:
if err := ensureBoxUnlocked(boxID); err != nil {
return err
} Try / catch
// In writeImportedTree caller, handle the locked-notebook error
err := writeImportedTree(boxID, syPath, newSyPath, relPath, data)
if err != nil {
if err.Error() == Conf.Language(314) {
// Prompt user to unlock, or skip this file
util.PushMsg(Conf.Language(314))
return err
}
} Prevention
- Always call the unlock API or enter the master password before importing into encrypted notebooks.
- Check IsEncryptedBox and GetDEKIfUnlocked before calling import functions.
- In batch import workflows, verify the unlock state once at the start and re-check if the operation is long-running.
- Handle notebook auto-lock timeouts by re-unlocking if the import takes longer than the idle timeout.
When it happens
Trigger: Calling writeImportedTree (internally from ImportSYZip or ImportData) for a boxID where IsEncryptedBox returns true but isBoxUnlockedForAccess returns false. This happens when the encrypted notebook exists but the user has not entered the master password in the current session, or the notebook was locked/unmounted after unlocking.
Common situations: Importing content into an encrypted notebook after a kernel restart without re-unlocking. Notebook was auto-locked due to idle timeout. Importing via API or automation without first calling the unlock endpoint. Race condition where the notebook is locked between the start of import and the write step.
Related errors
- encrypted notebook is locked, please unlock it first
- Cannot import a key backup while encrypted notebooks are ena
- Decryption failed: incorrect key or corrupted data
- encrypted notebook is locked, please unlock it first
- Please unlock the encrypted notebook first
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/f3d683e683dd3eec.
Report an issue: GitHub.