siyuan-note/siyuan · warning

password must not be empty

Error message

password must not be empty

What it means

EnableEncryptedNotebookWithSync rejects an empty password immediately (len(password) == 0) before any synchronization or key generation. This is the entry-point guard for the sync-then-enable flow; passing an empty password would otherwise produce a meaningless sync round and risk creating a key derived from an empty secret. The message is the hardcoded 'password must not be empty' (not a localized string).

Source

Thrown at kernel/model/crypto.go:952

	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 251596fc0d)

Solutions

  1. Validate non-empty password in the UI before invoking the enable flow.
  2. Programmatically guard: `if password == "" { return errors.New("password required") }`.
  3. Ensure the password input is bound to the actual form field, not an unset default.

Example fix

// before
err := model.EnableEncryptedNotebookWithSync(password)

// after
if password == "" {
    return errors.New("password required")
}
err := model.EnableEncryptedNotebookWithSync(password)
Defensive patterns

Strategy: validation

Validate before calling

// Guard before calling the sync-then-enable entry point.
if len(password) == 0 {
    return errors.New("password required")
}
err := model.EnableEncryptedNotebookWithSync(password)

Prevention

When it happens

Trigger: EnableEncryptedNotebookWithSync is called with an empty byte string. Typical when the UI submits the enable form without a password entry, or a programmatic caller passes an unset variable.

Common situations: User clicks 'enable encryption' without entering a password; frontend validation bypassed; automation passing an empty env variable; password field cleared before submit.

Related errors


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