siyuan-note/siyuan · error

Encrypted notebooks do not support this operation

Error message

Encrypted notebooks do not support this operation

What it means

kernel/model/blockial.go:367, from setNodeAttrs0 (language key 313): if the target block lives in an encrypted notebook (IsEncryptedBox) and the requested attributes include 'bookmark' or 'tags' (case-insensitive), the write is refused with 'Encrypted notebooks do not support this operation'. Rationale (per the code comment): bookmarks and tags rely on the global SQLite aggregation, but an encrypted notebook is an isolated island, so global attr features are unavailable there.

Solutions

  1. Skip bookmark/tags attributes for blocks in encrypted notebooks; use custom-prefixed attrs (e.g. custom-mytag) which are allowed, since they stay document-local.
  2. Un-encrypt the notebook if global bookmark/tag features are required there.
  3. Detect encrypted notebooks up front via the notebook list API and branch your logic.

Example fix

// before
await setBlockAttrs(id, { tags: "#project" }); // id is in an encrypted notebook

// after
await setBlockAttrs(id, { "custom-mytag": "project" }); // document-local attr is allowed
Defensive patterns

Strategy: validation

Validate before calling

// Skip global-only attrs when the target notebook is encrypted
const boxes = (await (await fetch("/api/notebook/lsNotebooks", { method: "POST" })).json()).data?.notebooks ?? [];
const encrypted = new Set(boxes.filter((b: any) => b.enclosed ?? b.encrypted).map((b: any) => b.id));
// for the target's box (from /api/query root_box_id), filter:
function safeAttrs(boxID: string, attrs: Record<string, string>) {
  if (!encrypted.has(boxID)) return attrs;
  return Object.fromEntries(Object.entries(attrs)
    .filter(([k]) => !['bookmark', 'tags'].includes(k.toLowerCase())));
}

Type guard

const isEncryptedNotebook = (box: { enclosed?: boolean } | undefined) => !!box?.enclosed;

Try / catch

try {
  await setBlockAttrs(id, attrs);
} catch (e) {
  if (/Encrypted notebooks do not support this operation/.test(e.message)) {
    const { bookmark, tags, ...rest } = attrs;
    await setBlockAttrs(id, rest); // apply what is allowed
  } else throw e;
}

Prevention

When it happens

Trigger: POST /api/attr/setBlockAttrs or /api/attr/batchSetBlockAttrs with attrs {"bookmark": ...} or {"tags": ...} for a block whose notebook is encrypted (locked with a passcode); setting a bookmark or tag from the UI or API inside an encrypted notebook.

Common situations: Automation that applies uniform bookmarks/tags across all notebooks without checking notebook encryption state; users enabling notebook encryption later, breaking existing tagging flows.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/32fa6a84e8998688. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/blockial.go:367

	IncSync()
	newAttrs := parse.IAL2Map(node.KramdownIAL)
	cache.PutBlockIALInBox(node.ID, tree.Box, newAttrs)
	if oldAttrs[DocSortModeAttr] != newAttrs[DocSortModeAttr] && ast.NodeDocument == node.Type {
		cache.RemoveDocIALInBox(tree.Path, tree.Box)
		cache.PutDocIALInBox(tree.Path, tree.Box, newAttrs)
	}
	pushBlockAttrs(oldAttrs, node)
	pushDocSortModeChanged(oldAttrs, node, tree)
	return
}

func setNodeAttrs0(node *ast.Node, nameValues map[string]string, boxID string) (oldAttrs map[string]string, err error) {
	// 加密笔记本不支持书签和标签(依赖全局 SQLite 聚合,加密笔记本是孤岛)
	if IsEncryptedBox(boxID) && boxID != "" {
		for name := range nameValues {
			switch strings.ToLower(name) {
			case "bookmark", "tags":
				err = errors.New(Conf.Language(313))
				return
			}
		}
	}
	oldAttrs = parse.IAL2Map(node.KramdownIAL)
	newAttrsUnEsc := parse.IAL2MapUnEsc(node.KramdownIAL)
	for name := range nameValues {
		if "fold" == strings.ToLower(name) {
			delete(newAttrsUnEsc, "heading-fold")
			break
		}
	}

	for name, value := range nameValues {
		value = util.RemoveInvalidRetainCtrl(value)
		value = strings.TrimSpace(value)
		lowerName := strings.ToLower(name)
		// 转换为小写再验证属性名

View on GitHub (pinned to afa823b6b4)