{"record":{"id":"befd8938458b4a11","repo":"siyuan-note/siyuan","slug":"conf-language-385","errorCode":null,"errorMessage":"Conf.Language(385)","messagePattern":"Conf\\.Language\\(385\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/import.go","lineNumber":372,"sourceCode":"\t\t})\n\t}\n\treturn ret\n}\n\n// checkEncryptedImportDeck 检查导入包里的闪卡数据。\n// 加密笔记本是孤岛，闪卡牌组与调度依赖全局数据库，因此必须拒绝导入；\n// 报错会指出包内哪些文档的卡片位于牌组中，便于用户在源笔记本中移除闪卡后重新导出。\nfunc checkEncryptedImportDeck(unzipRootPath string, trees map[string]*parse.Tree, blockIDs map[string]string) error {\n\tstorageRiffDir := filepath.Join(unzipRootPath, \"storage\", \"riff\")\n\tif !gulu.File.IsExist(storageRiffDir) {\n\t\treturn nil\n\t}\n\n\tdeck, loadErr := riff.LoadDeck(storageRiffDir, builtinDeckID, Conf.Flashcard.RequestRetention, Conf.Flashcard.MaximumInterval, Conf.Flashcard.Weights)\n\tif nil != loadErr || nil == deck {\n\t\t// 牌组无法解析时仍要拒绝导入，此时无法指出具体文档，只报告包内牌组路径\n\t\tlogging.LogErrorf(\"load imported deck [%s] failed: %s\", storageRiffDir, loadErr)\n\t\treturn errors.New(fmt.Sprintf(Conf.Language(385), filepath.ToSlash(filepath.Join(\"storage\", \"riff\"))))\n\t}\n\n\tvar deckDocs []string\n\tblockDocTitles := importedBlockDocTitles(trees)\n\tfor _, blockID := range deck.GetBlockIDs() {\n\t\t// 卡片记录的是导出时的旧块 ID，需按导入时重建的映射换算\n\t\tnewBlockID := blockIDs[blockID]\n\t\tif \"\" == newBlockID {\n\t\t\tnewBlockID = blockID\n\t\t}\n\t\tif title := blockDocTitles[newBlockID]; \"\" != title {\n\t\t\tdeckDocs = append(deckDocs, title)\n\t\t} else {\n\t\t\t// 卡片所属块不在本次导入范围内，保留块 ID 供用户定位\n\t\t\tdeckDocs = append(deckDocs, newBlockID)\n\t\t}\n\t}\n\tif 0 == len(deckDocs) {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/import.go#L354-L390","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import fs from \"fs\";\nconst riffDir = path.join(extractedRoot, \"storage\", \"riff\");\nif (targetNotebook.encrypted && fs.existsSync(riffDir)) {\n  throw new Error(\"Archive contains flashcard deck data; encrypted notebook import is not supported\");\n}","typeGuard":"const hasDeckData = (root) => { try { return require(\"fs\").existsSync(require(\"path\").join(root, \"storage\", \"riff\")); } catch { return false; } };","tryCatchPattern":"try {\n  await importSY(zipPath, boxID, toPath, createNotebook, autoDetect);\n} catch (e) {\n  if (e.message.includes(\"storage/riff\") || /385|deck/i.test(e.message)) {\n    console.warn(\"Flashcard deck data cannot be imported into an encrypted notebook; import into a plain notebook or strip storage/riff\");\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["import","flashcards","encrypted-notebook","corrupt-deck"],"backgroundTag":"unsupported-operation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}