siyuan-note/siyuan · error

CLI does not support encrypted notebook [%s]

Error message

CLI does not support encrypted notebook [%s]

What it means

Thrown by `rejectEncryptedNotebookCLI` when the command is `notebook random-icon` (without `--id`) or `export data`, AND at least one encrypted notebook exists in the workspace (`firstEncryptedNotebookID` returns a non-empty boxID). SiYuan encrypts notebook contents at rest; the CLI process is not an unlock path, so bulk operations over all notebooks are blocked to avoid leaking ciphertext handling or bypassing the in-app unlock flow. The error names the first encrypted box ID found.

Source

Thrown at kernel/cli/cmd/root.go:136

			return err
		}
		return nil
	},
}

// rejectEncryptedNotebookCLI 拒绝 CLI 对加密笔记本及其块的操作。
// 加密笔记本只能通过应用内专用流程解锁和操作,避免 CLI 进程成为明文或密文文件的旁路入口。
func rejectEncryptedNotebookCLI(cmd *cobra.Command, args []string) error {
	if cmd == serveCmd {
		return nil
	}
	if (cmd == notebookRandomIconCmd && !cmd.Flags().Changed("id")) || cmd == exportDataCmd {
		boxID, err := firstEncryptedNotebookID()
		if err != nil {
			return err
		}
		if boxID != "" {
			return fmt.Errorf("CLI does not support encrypted notebook [%s]", boxID)
		}
	}

	var encryptedTarget string
	checkID := func(id string) bool {
		if id == "" {
			return false
		}
		if model.IsEncryptedBox(id) {
			encryptedTarget = id
			return true
		}
		if bt := treenode.GetBlockTree(id); bt != nil && model.IsEncryptedBox(bt.BoxID) {
			encryptedTarget = bt.BoxID
			return true
		}
		return false
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. For `notebook random-icon`, target a specific non-encrypted notebook with `--id <boxID>` to skip the all-notebooks scan.
  2. For `export data`, decrypt or remove the encrypted notebook(s) via the GUI app first, or use the GUI's own export flow.
  3. If you must operate, ensure no encrypted notebooks are present in the workspace before running the CLI command.

Example fix

// before
siyuan export data
// after (target a specific notebook instead of all)
siyuan notebook random-icon --id 20240101000000nonencrypted
Defensive patterns

Strategy: validation

Validate before calling

// Before `notebook random-icon` (no --id) or `export data`, check for encrypted notebooks.
boxes, err := model.ListNotebooks()
if err != nil { log.Fatal(err) }
for _, b := range boxes {
    if model.IsEncryptedBox(b.ID) {
        log.Fatalf("encrypted notebook %s present — decrypt via GUI or target a specific notebook with --id", b.ID)
    }
}

Prevention

When it happens

Trigger: Running `siyuan notebook random-icon` (no `--id`) or `siyuan export data` while any notebook in the workspace is encrypted. The guard scans all notebooks via `model.ListNotebooks` and stops at the first encrypted one.

Common situations: Workspace has one or more password-protected notebooks; operator tries to bulk-export data or regenerate icons from the CLI without realizing encrypted notebooks exist; automating backups via `export data` against a mixed workspace.

Related errors


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