siyuan-note/siyuan · error

password must not be empty

Error message

password must not be empty

What it means

EnableEncryptedNotebookWithSync guards against an empty master password before doing any work. Enabling the encrypted-notebook feature requires a user-chosen master password from which the KEK and MasterSalt are derived; an empty string cannot be a valid password, so the call is rejected immediately with errors.New("password must not be empty"). This is the same guard as EnableEncryptedNotebook, applied before the pre-enable sync step.

Solutions

  1. Check the password is non-empty at the caller (form validation or API handler) before calling EnableEncryptedNotebookWithSync
  2. If the password comes from config/request JSON, verify the key is present and populated before unmarshalling/marshalling the call
  3. If this happens in tests, pass a real test password string instead of ""
  4. If the user intentionally wants no password, note that the encrypted-notebook feature requires one; there is no empty-password mode

Example fix

// before
err := model.EnableEncryptedNotebookWithSync(req.Password) // req.Password may be ""
// after
if strings.TrimSpace(req.Password) == "" {
    return errors.New("master password is required")
}
err := model.EnableEncryptedNotebookWithSync(req.Password)
Defensive patterns

Strategy: validation

Validate before calling

if password == "" {
    return errors.New("master password is required before enabling encrypted notebooks")
}

Prevention

When it happens

Trigger: Calling kernel/model.EnableEncryptedNotebookWithSync("") or with a password variable that was never populated (empty form field, missing config value, unset request parameter). Also occurs in tests such as TestRestoreNotebookCryptoConfigFromExistingBackup that invoke the function without supplying a password.

Common situations: Frontend sends an empty password field because the user left the dialog blank; a configuration/JSON payload omits the password key so it unmarshals to ""; a test helper forgets to set the password argument.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/f543dd6293461ecb. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/crypto.go:974

	return boxConf.Encrypted, nil
}

// cachedDEKs 缓存已解锁加密笔记本的 DEK,按 boxID 索引。
// KEK 不全局缓存("严格每笔记本单独解锁"语义):UnlockBox 临时派生 KEK 解出 DEK 后即丢弃 KEK,
// 仅保留 per-box DEK 供后续读写加解密。
var (
	cachedDEKs     = map[string][]byte{}
	cachedDEKsLock sync.RWMutex
)

// boxLastAccess 记录每个加密笔记本最近一次真实用户交互或显式保活时间(unix 纳秒),供自动锁定 cron 使用。
// key: boxID, value: *atomic.Int64。UnlockBox 成功时初始化,Unmount 时清理。
var boxLastAccess sync.Map

// EnableEncryptedNotebookWithSync 在启用前先完成同步;同步恢复了既有配置时只校验原主密码。
func EnableEncryptedNotebookWithSync(password string) error {
	if len(password) == 0 {
		return errors.New("password must not be empty")
	}
	if err := SyncDataBeforeEnableEncryptedNotebook(); err != nil {
		return err
	}

	// 同步可能已经从其他设备恢复了完整配置。此时校验用户输入的是原主密码,不能再创建新的密钥体系。
	if NotebookCryptoEnabled() {
		notebookCryptoMu.Lock()
		defer notebookCryptoMu.Unlock()
		kek, err := deriveKEK(password)
		if kek != nil {
			zeroAndClear(kek)
		}
		return err
	}
	return EnableEncryptedNotebook(password)
}

View on GitHub (pinned to 9f775e8a12)