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

  1. Unlock the encrypted notebook before importing: call the unlock API or enter the master password in the UI.
  2. Verify the notebook is in the unlocked state by checking IsEncryptedBox and isBoxUnlockedForAccess before calling import functions.
  3. If importing via API, ensure the unlock endpoint is called first and the session/token maintains the unlocked state.
  4. 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

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


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