siyuan-note/siyuan · error

Please unlock the encrypted notebook first

Error message

Please unlock the encrypted notebook first

What it means

writeImportedTree encrypts each rewritten .sy when the target box is encrypted; it calls GetDEKIfUnlocked, which fails when the notebook is locked (no data-encryption key cached in memory - after restart, auto-lock, or LockBox). Rather than writing plaintext into an encrypted notebook, the import is refused with Language(314) 'Please unlock the encrypted notebook first'.

Solutions

  1. Unlock the encrypted notebook in the UI (enter its passphrase), then re-run the import
  2. For automation, perform the unlock flow via API before calling import endpoints
  3. Alternatively import into a non-encrypted notebook first, then encrypt/migrate afterwards
Defensive patterns

Strategy: validation

Validate before calling

if model.IsEncryptedBox(boxID) {
    if _, err := model.GetDEKIfUnlocked(boxID); err != nil {
        // notebook is locked: prompt for passphrase / unlock via API before importing
        return err
    }
}
err := model.ImportSY(zipPath, boxID, toPath)

Type guard

func isLockedNotebookErr(err error) bool {
    return err != nil && err.Error() == model.Conf.Language(314)
}

Try / catch

if err := model.ImportSY(zipPath, boxID, toPath); err != nil {
    if err.Error() == model.Conf.Language(314) {
        // unlock the notebook, then retry the import once
    }
}

Prevention

When it happens

Trigger: importSY / importSYAuto / continueImportSY into an encrypted notebook that has not been unlocked in this kernel session. The failure surfaces per-document during the write-back loop (kernel/model/import.go:670 -> 1045).

Common situations: Importing right after an app restart before unlocking the notebook. Headless/API automation that never performs the unlock step. Auto-lock policy locking the box between starting and finishing a long import.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/f3d683e683dd3eec. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/import.go:1045

		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 afa823b6b4)