siyuan-note/siyuan · error
exporting encrypted and normal notebook resources together…
Error message
exporting encrypted and normal notebook resources together is not supported
What it means
A single export batch may contain resources from encrypted notebooks OR from normal notebooks, but not both. The mixed set has no consistent decrypt/copy strategy, so exportResourcesEncryptedBox rejects it when at least one encrypted-box resource and at least one normal resource are present.
Solutions
- Partition the resource list into encrypted and normal sets and issue separate ExportResources calls per set
- Handle the error in the UI by informing the user to export encrypted and normal notebook resources separately
Example fix
// before
ExportResources([]string{"encBox/assets/a.png", "normalBox/assets/b.png"})
// after
ExportResources([]string{"encBox/assets/a.png"})
ExportResources([]string{"normalBox/assets/b.png"}) Defensive patterns
Strategy: validation
Validate before calling
function partitionByEncryption(paths, isEncryptedBox) {
const encrypted = paths.filter(p => isEncryptedBox(p.split('/')[0]));
const normal = paths.filter(p => !isEncryptedBox(p.split('/')[0]));
return { encrypted, normal };
} Try / catch
try { await exportResources(mixedPaths); }
catch (e) {
if (String(e).includes('encrypted and normal notebook resources together')) {
const { encrypted, normal } = partitionByEncryption(mixedPaths, isEncrypted);
await exportResources(encrypted);
await exportResources(normal);
}
} Prevention
- Partition mixed selection exports into encrypted-only and normal-only batches
- Inform users that encrypted and normal notebook resources must be exported separately
- Track notebook encryption state in the UI before assembling export lists
When it happens
Trigger: ExportResources called with asset paths where some belong to encrypted boxes (IsEncryptedBox true) and others to regular notebooks.
Common situations: Multi-select export of images across notebooks after enabling encryption on some notebooks; plugin collecting all assets referenced by a document that embeds cross-notebook assets.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- exporting non-asset files from encrypted notebooks is not…
- exporting resources across encrypted notebook boundaries is…
- managed export is unavailable
- 314
- 314
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/a86c37051d7abf19.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/export.go:1022
}
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, accessChecker ...EmbedBlockAccessChecker) (retStdHTML string) {
if exportErr := withExportReadLockByBlockID(id, func() error {
blockRefMode := Conf.Export.BlockRefMode
bt := getExportBlockTree(id)
if nil == bt {
return nil
}
tree := prepareExportTree(bt)
if numberErr := applyHeadingNumbersForExport(tree, bt, false); nil != numberErr {
return numberErr
}
tree, exportTreeErr := exportTree(tree, false, true, false, true,
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,View on GitHub (pinned to 9f775e8a12)