siyuan-note/siyuan · error
exporting non-asset files from encrypted notebooks is not su
Error message
exporting non-asset files from encrypted notebooks is not supported
What it means
Returned by exportResourcesEncryptedBox when a resource path resolves into an encrypted notebook (ExtractBoxIDFromAssetsPath returns a boxID that IsEncryptedBox confirms) but the path is NOT under that notebook's assets/ directory (gulu.File.IsSubPath fails). SiYuan only supports exporting asset files from encrypted notebooks via the managed assets folder; exporting arbitrary .sy or other files from an encrypted box is refused to avoid leaking ciphertext structure.
Source
Thrown at kernel/model/export.go:937
}
// exportResourcesEncryptedBox 校验资源导出是否跨越加密边界,并返回唯一允许的加密来源 boxID。
func exportResourcesEncryptedBox(resourcePaths []string) (encryptedBoxID string, err error) {
hasNormalResource := false
for _, resourcePath := range resourcePaths {
resourceFullPath := filepath.Join(util.WorkspaceDir, resourcePath)
if !util.IsAbsPathInWorkspace(resourceFullPath) {
return "", errors.New("resource path [" + resourcePath + "] is not in workspace")
}
boxID := ExtractBoxIDFromAssetsPath(resourceFullPath)
if boxID == "" || !IsEncryptedBox(boxID) {
hasNormalResource = true
continue
}
assetsPath := filepath.Join(util.DataDir, boxID, "assets")
if !gulu.File.IsSubPath(assetsPath, resourceFullPath) {
return "", errors.New("exporting non-asset files from encrypted notebooks is not supported")
}
if encryptedBoxID == "" {
encryptedBoxID = boxID
} else if encryptedBoxID != boxID {
return "", errors.New("exporting resources across encrypted notebook boundaries is not supported")
}
}
if encryptedBoxID != "" && hasNormalResource {
return "", errors.New("exporting encrypted and normal notebook resources together is not supported")
}
return
}
func ExportPreview(id string, fillCSSVar bool) (retStdHTML string) {
if exportErr := withExportReadLockByBlockID(id, func() error {
blockRefMode := Conf.Export.BlockRefMode
bt := getExportBlockTree(id)
if nil == bt {View on GitHub (pinned to 251596fc0d)
Solutions
- Only pass asset paths (under data/<box>/assets/) of encrypted notebooks to ExportResources.
- To export a document from an encrypted notebook, use ExportSYs/ExportMarkdownHTML/ExportDocx (the doc-level export path with the read-lock guard) instead.
- Filter resource paths at the caller to the encrypted box's assets/ subtree before calling.
Example fix
// before — passing a .sy path from an encrypted box
model.ExportResources([]string{"data/20230101abc/20230101xyz.sy"}, name)
// after — export the document via the doc-level path, or pass only assets
model.ExportResources([]string{"data/20230101abc/assets/image.png"}, name) Defensive patterns
Strategy: validation
Validate before calling
// Ensure encrypted-notebook resources are strictly under that box's assets/ dir
for _, p := range resourcePaths {
full := filepath.Join(util.WorkspaceDir, p)
boxID := ExtractBoxIDFromAssetsPath(full)
if boxID != "" && IsEncryptedBox(boxID) {
assetsPath := filepath.Join(util.DataDir, boxID, "assets")
if !gulu.File.IsSubPath(assetsPath, full) {
return fmt.Errorf("non-asset path in encrypted box %s: %s", boxID, p)
}
}
} Type guard
// isEncryptedBoxAsset reports whether p is under the encrypted box's assets/ folder.
func isEncryptedBoxAsset(p string) bool {
boxID := ExtractBoxIDFromAssetsPath(p)
if boxID == "" || !IsEncryptedBox(boxID) {
return false
}
return gulu.File.IsSubPath(filepath.Join(util.DataDir, boxID, "assets"), p)
} Prevention
- Only pass data/<encrypted-box>/assets/* paths to ExportResources.
- Use the document-export endpoints for encrypted .sy files, not the resource endpoint.
- Filter resource selections to the assets/ subtree of encrypted notebooks.
When it happens
Trigger: POST /api/export/exportResources with a path like data/<encrypted-box>/2023...sy or a file under the notebook root rather than under data/<encrypted-box>/assets/. The user (or a plugin) selected a document or internal file from an encrypted notebook instead of an asset.
Common situations: User tries to export a .sy doc or a non-asset file from an encrypted notebook via the resource-export endpoint instead of the document-export endpoint. Plugin iterates notebook files generically without filtering to assets/.
Related errors
- exporting resources across encrypted notebook boundaries is
- exporting encrypted and normal notebook resources together i
- CLI does not support encrypted notebook [%s]
- CLI does not support files in encrypted notebooks
- read image failed: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/99d8e2f12f2dc6db.
Report an issue: GitHub.