siyuan-note/siyuan · error
path belongs to encrypted notebook [%s]: %s
Error message
path belongs to encrypted notebook [%s]: %s
What it means
Thrown by the shared `absPath` helper when the resolved absolute path falls inside an encrypted notebook. `model.EncryptedRawPathBoxID` checks both the path itself and its longest existing parent (to defeat symlink bypass), returning the box ID if the path belongs to a notebook flagged as encrypted. The CLI deliberately blocks raw file access to encrypted notebook data so ciphertext is never read or written outside the decryption layer.
Source
Thrown at kernel/cli/cmd/file.go:47
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/util"
"github.com/spf13/cobra"
)
var fileCmd = &cobra.Command{
Use: "file",
Short: "Workspace file operations",
}
func absPath(rel string) (string, error) {
rel = filepath.Clean(strings.ReplaceAll(rel, "/", string(os.PathSeparator)))
abs := filepath.Join(util.WorkspaceDir, rel)
if !gulu.File.IsSubPath(util.WorkspaceDir, abs) {
return "", fmt.Errorf("path escapes workspace: %s", rel)
}
if boxID := model.EncryptedRawPathBoxID(abs); boxID != "" {
return "", fmt.Errorf("path belongs to encrypted notebook [%s]: %s", boxID, rel)
}
return abs, nil
}
var fileListCmd = &cobra.Command{
Use: "list <path>",
Short: "List directory contents",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
dir, err := absPath(args[0])
if err != nil {
return err
}
entries, err := os.ReadDir(dir)
if err != nil {
return err
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)View on GitHub (pinned to 251596fc0d)
Solutions
- Decrypt or disable encryption on the notebook in the GUI before raw CLI access
- Use a higher-level command that goes through the decryption layer rather than `file` subcommands
- Exclude encrypted notebook IDs from batch file scripts
Example fix
// before siyuan file read data/20200101-encsecret/doc.sy // after # Decrypt notebook in the GUI first, or use a model-level command: # Settings - Security - disable encryption on that notebook
Defensive patterns
Strategy: validation
Validate before calling
// Before batch file ops, filter out encrypted notebooks:
for _, box := range openNotebooks {
if model.IsEncryptedBox(box.ID) { continue }
// only operate on box.ID paths
} Prevention
- Track which notebook IDs are encrypted and exclude them from raw file scripts
- Prefer model-level commands over `file` subcommands for encrypted notebooks
- Decrypt a notebook in the GUI before any raw CLI access to its files
When it happens
Trigger: Any `file` subcommand targeting a path under `data/<encryptedBoxID>/...`. The path may look normal but `EncryptedRawPathBoxID` resolves the box ID from the assets path and confirms `IsEncryptedBox(boxID)` is true.
Common situations: Forgetting a notebook was encrypted in settings; scripts iterating all notebooks without filtering encrypted ones; trying to grep or copy files out of an encrypted notebook for a backup.
Related errors
- path escapes workspace: %s
- --notebook is required
- --notebook is required
- parent path not found: %s
- --name is required
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/30b74e43d7ea011a.
Report an issue: GitHub.