siyuan-note/siyuan · error
exporting encrypted and normal notebook resources together i
Error message
exporting encrypted and normal notebook resources together is not supported
What it means
Returned by exportResourcesEncryptedBox after the loop when at least one resource came from an encrypted notebook (encryptedBoxID set) AND at least one came from a normal (non-encrypted) source (hasNormalResource true). Mixing encrypted and plaintext resources in a single export is refused because the encrypted path requires holding one box's read-lock and decrypting, while the normal path does not — combining them would leak which resources are encrypted and complicate the lock scope.
Source
Thrown at kernel/model/export.go:946
}
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 {
return nil
}
tree := prepareExportTree(bt)
if numberErr := applyHeadingNumbersForExport(tree, bt, false); nil != numberErr {
return numberErr
}
tree = exportTree(tree, false, false, true,
blockRefMode, Conf.Export.BlockEmbedMode, Conf.Export.FileAnnotationRefMode,View on GitHub (pinned to 251596fc0d)
Solutions
- Partition the resource list: call ExportResources once for the encrypted-box assets and once for the normal assets.
- Filter the selection so it is entirely encrypted or entirely normal before exporting.
- If a single archive is required, export each group separately and merge the zips afterward.
Example fix
// before — encrypted + normal mixed
model.ExportResources([]string{
"data/encBox/assets/secret.png", // encrypted
"data/notebook/assets/public.png", // normal
}, name)
// after — split by encryption status
model.ExportResources([]string{"data/encBox/assets/secret.png"}, name)
model.ExportResources([]string{"data/notebook/assets/public.png"}, name) Defensive patterns
Strategy: validation
Validate before calling
// Ensure resources are not a mix of encrypted and normal
hasEnc, hasNormal := false, false
for _, p := range resourcePaths {
boxID := ExtractBoxIDFromAssetsPath(filepath.Join(util.WorkspaceDir, p))
if boxID != "" && IsEncryptedBox(boxID) {
hasEnc = true
} else {
hasNormal = true
}
}
if hasEnc && hasNormal {
return errors.New("partition encrypted and normal resources into separate exports")
} Prevention
- Partition the resource list by encryption status before exporting.
- Never batch encrypted and plaintext assets in one ExportResources call.
- Merge the separately-produced zips afterward if a single archive is required.
When it happens
Trigger: POST /api/export/exportResources with resourcePaths containing both data/<encrypted-box>/assets/* entries and entries from normal notebooks or the global assets folder. The loop sets encryptedBoxID and hasNormalResource, then the post-loop check fires.
Common situations: User selects a mix of encrypted-notebook assets and normal-notebook/global assets and triggers a single resource export. A plugin naively batches all referenced assets without distinguishing encrypted sources.
Related errors
- exporting non-asset files from encrypted notebooks is not su
- exporting resources across encrypted notebook boundaries is
- CLI does not support encrypted notebook [%s]
- CLI does not support files in encrypted notebooks
- encrypted notebook is not accessible
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/a86c37051d7abf19.
Report an issue: GitHub.