siyuan-note/siyuan · error
Encrypted notebooks do not support this operation
Error message
Encrypted notebooks do not support this operation
What it means
Thrown by ValidateFlashcardBlockIDs when at least one block ID fails the isSupportedFlashcardBlock check. That function returns false if treenode.GetBlockTreeInExactBox(blockID, "") returns nil (the block does not exist) OR if the block lives in an encrypted notebook (IsEncryptedBox(bt.BoxID) is true). The error message uses Conf.Language(313) = "Encrypted notebooks do not support this operation". This is a gatekeeper function that prevents encrypted content from entering the global flashcard deck store.
Source
Thrown at kernel/model/flashcard.go:47
"github.com/88250/gulu"
"github.com/88250/lute/ast"
"github.com/88250/lute/parse"
"github.com/open-spaced-repetition/go-fsrs/v3"
"github.com/siyuan-note/filelock"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/riff"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
)
// ValidateFlashcardBlockIDs 只允许普通笔记本中可确认存在的块进入全局闪卡存储。
func ValidateFlashcardBlockIDs(blockIDs []string) error {
for _, blockID := range blockIDs {
if !isSupportedFlashcardBlock(blockID) {
return errors.New(Conf.Language(313))
}
}
return nil
}
func validateFlashcardTree(rootID string) error {
return ValidateFlashcardBlockIDs([]string{rootID})
}
func isSupportedFlashcardBlock(blockID string) bool {
bt := treenode.GetBlockTreeInExactBox(blockID, "")
return bt != nil && !IsEncryptedBox(bt.BoxID)
}
func filterSupportedFlashcards(cards []riff.Card) (ret []riff.Card) {
for _, card := range cards {
if card == nil || !isSupportedFlashcardBlock(card.BlockID()) {
continueView on GitHub (pinned to 251596fc0d)
Solutions
- If the block is in an encrypted notebook, move it to a non-encrypted notebook first, or decrypt the notebook — encrypted content is fundamentally excluded from flashcard decks by design.
- If the block should exist, verify it is still present via the block lookup endpoint — it may have been deleted.
- As an API client, filter block IDs through isSupportedFlashcardBlock equivalent logic (exists + non-encrypted) before calling flashcard APIs.
Example fix
// before
await post('/api/riff/addRiffCards', { deckID, blockIDs: [...allSelectedBlocks] })
// after — exclude blocks from encrypted notebooks and non-existent blocks
const validBlockIDs = allSelectedBlocks.filter(id => {
const bt = getBlockInfo(id)
return bt && !bt.encrypted
})
await post('/api/riff/addRiffCards', { deckID, blockIDs: validBlockIDs }) Defensive patterns
Strategy: validation
Validate before calling
// Filter out blocks from encrypted notebooks before flashcard operations
function isFlashcardSupported(bt) {
return bt != null && !bt.encrypted
}
const supportedBlockIDs = blockIDs.filter(id => isFlashcardSupported(blockTreeCache[id])) Type guard
// Type guard: check if a block can be used as a flashcard
function isFlashcardEligible(bt: { boxID: string; encrypted: boolean } | null): bt is { boxID: string; encrypted: false } {
return bt != null && !bt.encrypted
} Prevention
- Never add blocks from encrypted notebooks to flashcard decks — this is a fundamental design restriction.
- Verify block existence before adding to flashcard operations.
- Filter block lists through an encrypted-notebook check before any riff API call.
When it happens
Trigger: Calling any flashcard API that routes through ValidateFlashcardBlockIDs (such as adding blocks to a deck or resetting flashcards) with a block ID that either does not exist in the block tree or resides in an encrypted notebook. The isSupportedFlashcardBlock check uses GetBlockTreeInExactBox with an empty box filter, so it looks up the block across all boxes.
Common situations: User selects blocks from an encrypted notebook and tries to add them as flashcards; a block was deleted after the UI rendered it but before the flashcard API call; an API client passes a stale or fabricated block ID.
Related errors
- path belongs to encrypted notebook [%s]: %s
- invalid .sy base name [%s]: must end with .sy
- invalid .sy base name [%s]: stem is not a node ID
- Encrypted notebooks do not support this operation
- password must not be empty
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/ba0c6ed7508ce685.
Report an issue: GitHub.