{"record":{"id":"1674a3d9e68d3116","repo":"siyuan-note/siyuan","slug":"conf-language-313","errorCode":null,"errorMessage":"Conf.Language(313)","messagePattern":"Conf\\.Language\\(313\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/flashcard.go","lineNumber":55,"sourceCode":"\t\"github.com/siyuan-note/siyuan/kernel/cache\"\n\t\"github.com/siyuan-note/siyuan/kernel/sql\"\n\t\"github.com/siyuan-note/siyuan/kernel/treenode\"\n\t\"github.com/siyuan-note/siyuan/kernel/util\"\n)\n\n// ValidateFlashcardBlockIDs 只允许普通笔记本中可确认存在的块进入全局闪卡存储。\nfunc ValidateFlashcardBlockIDs(blockIDs []string) error {\n\treturn validateFlashcardBlockIDs(blockIDs, treenode.GetBlockTree, IsEncryptedBox)\n}\n\nfunc validateFlashcardBlockIDs(blockIDs []string, getBlockTree func(string) *treenode.BlockTree, isEncryptedBox func(string) bool) error {\n\tfor _, blockID := range blockIDs {\n\t\tbt := getBlockTree(blockID)\n\t\tif bt == nil {\n\t\t\treturn errors.New(Conf.Language(180))\n\t\t}\n\t\tif isEncryptedBox(bt.BoxID) {\n\t\t\treturn errors.New(Conf.Language(313))\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateFlashcardTree(rootID string) error {\n\treturn ValidateFlashcardBlockIDs([]string{rootID})\n}\n\nfunc isSupportedFlashcardBlock(blockID string) bool {\n\tbt := treenode.GetBlockTreeInExactBox(blockID, \"\")\n\treturn bt != nil && !IsEncryptedBox(bt.BoxID)\n}\n\nfunc filterSupportedFlashcards(cards []riff.Card) (ret []riff.Card) {\n\tfor _, card := range cards {\n\t\tif card == nil || !isSupportedFlashcardBlock(card.BlockID()) {\n\t\t\tcontinue","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/flashcard.go#L37-L73","documentation":"validateFlashcardBlockIDs reports, through the localized message Conf.Language(313), that the block belongs to an encrypted notebook (isEncryptedBox). Encrypted notebooks are excluded from flashcard operations because their data cannot be processed by the RIFF scheduler index in plaintext.","triggerScenarios":"Calling ValidateFlashcardBlockIDs with a blockID whose bt.BoxID refers to a notebook encrypted by the kernel's encrypted-notebook feature; any flashcard create/remove/reset call that validates such block IDs.","commonSituations":"A user with a mix of encrypted and normal notebooks selects blocks from an encrypted notebook; a plugin enumerates all blocks across notebooks without filtering out encrypted ones; scripts written before encrypted notebooks were introduced.","solutions":["Use flashcards only for blocks in unencrypted notebooks; move the block content to a normal notebook if flashcards are required.","Filter candidate block IDs by notebook before calling the API (check the notebook's encryption status via the notebook list API).","Do not attempt to bypass the check — encrypted-notebook data must remain authenticated and unprocessed by non-supporting features."],"exampleFix":"// before\nawait addRiffCards(blockIDs)\n// after\nconst enc = await getEncryptedNotebookIDs()\nconst ok = blockIDs.filter(id => !enc.has(blockToBox[id]))\nawait addRiffCards(ok)","handlingStrategy":"validation","validationCode":"const notebooks = await fetchPost('/api/notebook/lsNotebooks', {})\nconst encrypted = new Set(notebooks.filter(nb => nb.closed === false && nb.isEncrypted).map(nb => nb.id))\nconst usable = blockIDs.filter(id => !encrypted.has(blockToBox(id)))","typeGuard":null,"tryCatchPattern":"try {\n  await addRiffCards(ids)\n} catch (e) {\n  if (String(e.msg).includes(Lang313)) showMsg('Flashcards are not supported for encrypted notebooks', 'error')\n  else throw e\n}","preventionTips":["Filter out blocks from encrypted notebooks before any flashcard API","Track which notebooks are encrypted in your plugin's configuration","Document the encrypted-notebook limitation in scripts that enumerate all blocks"],"tags":["flashcards","encrypted-notebook","unsupported-operation","validation"],"backgroundTag":"unsupported-operation","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}