siyuan-note/siyuan · error
Conf.Language(385)
Error message
Conf.Language(385)
What it means
checkEncryptedImportDeck rejects importing flashcard deck data (storage/riff) into an encrypted notebook. When the packaged deck cannot be loaded/parsed, no specific documents can be identified, so the error (i18n key 385) reports the archive-internal deck path storage/riff instead. Import is refused because deck scheduling depends on the global database.
Solutions
- Import into a non-encrypted notebook, where deck data is supported
- Fix or regenerate the storage/riff deck data in the source notebook and re-export
- Remove the storage/riff directory from the archive if the flashcards are not needed
Defensive patterns
Strategy: validation
Validate before calling
import fs from "fs";
const riffDir = path.join(extractedRoot, "storage", "riff");
if (targetNotebook.encrypted && fs.existsSync(riffDir)) {
throw new Error("Archive contains flashcard deck data; encrypted notebook import is not supported");
} Type guard
const hasDeckData = (root) => { try { return require("fs").existsSync(require("path").join(root, "storage", "riff")); } catch { return false; } }; Try / catch
try {
await importSY(zipPath, boxID, toPath, createNotebook, autoDetect);
} catch (e) {
if (e.message.includes("storage/riff") || /385|deck/i.test(e.message)) {
console.warn("Flashcard deck data cannot be imported into an encrypted notebook; import into a plain notebook or strip storage/riff");
} else { throw e; }
} Prevention
- Never import archives containing storage/riff into encrypted notebooks
- Validate deck data integrity in the source notebook before exporting
- Keep flashcard usage restricted to non-encrypted notebooks
When it happens
Trigger: Importing a .sy.zip that contains a storage/riff directory into an encrypted notebook when riff.LoadDeck fails or returns a nil deck (corrupt or unreadable deck data).
Common situations: Corrupted or hand-edited storage/riff deck files inside an exported notebook archive; deck format produced by a different SiYuan version; importing flashcard-bearing notebook exports into encrypted notebooks.
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
- Conf.Language(313)
- Conf.Language(386)
- Encrypted notebooks do not support this operation
- Conf.Language(313)
- Conf.Language(313)
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/befd8938458b4a11.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/import.go:372
})
}
return ret
}
// checkEncryptedImportDeck 检查导入包里的闪卡数据。
// 加密笔记本是孤岛,闪卡牌组与调度依赖全局数据库,因此必须拒绝导入;
// 报错会指出包内哪些文档的卡片位于牌组中,便于用户在源笔记本中移除闪卡后重新导出。
func checkEncryptedImportDeck(unzipRootPath string, trees map[string]*parse.Tree, blockIDs map[string]string) error {
storageRiffDir := filepath.Join(unzipRootPath, "storage", "riff")
if !gulu.File.IsExist(storageRiffDir) {
return nil
}
deck, loadErr := riff.LoadDeck(storageRiffDir, builtinDeckID, Conf.Flashcard.RequestRetention, Conf.Flashcard.MaximumInterval, Conf.Flashcard.Weights)
if nil != loadErr || nil == deck {
// 牌组无法解析时仍要拒绝导入,此时无法指出具体文档,只报告包内牌组路径
logging.LogErrorf("load imported deck [%s] failed: %s", storageRiffDir, loadErr)
return errors.New(fmt.Sprintf(Conf.Language(385), filepath.ToSlash(filepath.Join("storage", "riff"))))
}
var deckDocs []string
blockDocTitles := importedBlockDocTitles(trees)
for _, blockID := range deck.GetBlockIDs() {
// 卡片记录的是导出时的旧块 ID,需按导入时重建的映射换算
newBlockID := blockIDs[blockID]
if "" == newBlockID {
newBlockID = blockID
}
if title := blockDocTitles[newBlockID]; "" != title {
deckDocs = append(deckDocs, title)
} else {
// 卡片所属块不在本次导入范围内,保留块 ID 供用户定位
deckDocs = append(deckDocs, newBlockID)
}
}
if 0 == len(deckDocs) {View on GitHub (pinned to 9f775e8a12)