siyuan-note/siyuan · warning

Encrypted notebooks do not support this operation

Error message

Encrypted notebooks do not support this operation

What it means

Thrown by ListDocTree when the caller requests flashcard mode (flashcard=true) on a notebook that is encrypted (IsEncryptedBox returns true). Conf.Language(313) = 'Encrypted notebooks do not support this operation'. SiYuan treats encrypted notebooks as crypto-isolated — their content is decrypted on-demand and the flashcard (spaced repetition) subsystem cannot index or enumerate block IDs inside them, so any flashcard-related tree listing is blocked at the entry point.

Source

Thrown at kernel/model/file.go:388

	return ret.String()
}

type FileInfo struct {
	path  string
	name  string
	size  int64
	isdir bool
}

func ListDocTree(boxID, listPath string, sortMode int, flashcard, showHidden bool, maxListCount int) (ret []*File, totals int, err error) {
	//os.MkdirAll("pprof", 0755)
	//cpuProfile, _ := os.Create("pprof/cpu_profile_list_doc_tree")
	//pprof.StartCPUProfile(cpuProfile)
	//defer pprof.StopCPUProfile()

	ret = []*File{}
	if flashcard && IsEncryptedBox(boxID) {
		return nil, 0, errors.New(Conf.Language(313))
	}

	var deck *riff.Deck
	var deckBlockIDs []string
	if flashcard {
		deck = Decks[builtinDeckID]
		if nil == deck {
			return
		}

		deckBlockIDs = deck.GetBlockIDs()
	}

	box := Conf.Box(boxID)
	if nil == box {
		return nil, 0, errors.New(Conf.Language(0))
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Do not pass flashcard=true for encrypted notebooks — check IsEncryptedBox(boxID) before calling ListDocTree.
  2. If flashcard review is needed, move or export the relevant documents to a non-encrypted notebook first.
  3. In UI code, disable or hide the flashcard toggle when the current notebook is encrypted.
  4. For API consumers, query notebook metadata first and skip flashcard mode for encrypted boxes.

Example fix

// before
files, totals, err := model.ListDocTree(boxID, path, sortMode, true, showHidden, max)

// after
flashcard := true
if model.IsEncryptedBox(boxID) {
    flashcard = false
}
files, totals, err := model.ListDocTree(boxID, path, sortMode, flashcard, showHidden, max)
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: skip flashcard mode for encrypted notebooks
if model.IsEncryptedBox(boxID) {
    flashcard = false // or return an error / skip the call
}

Type guard

func canUseFlashcard(boxID string) bool {
    return !model.IsEncryptedBox(boxID)
}

Prevention

When it happens

Trigger: Calling ListDocTree(boxID, listPath, sortMode, flashcard=true, showHidden, maxListCount) where boxID refers to an encrypted notebook. The flashcard && IsEncryptedBox(boxID) guard at line 387 fires before any deck or file lookup occurs.

Common situations: A user opens the flashcard review UI while the active notebook is encrypted. A plugin or API client iterates all notebooks with flashcard=true without filtering out encrypted ones. A notebook was encrypted after the user had already been browsing flashcards in it.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/e3f7376eb00ed30b. Report an issue: GitHub.