{"record":{"id":"32fa6a84e8998688","repo":"siyuan-note/siyuan","slug":"encrypted-notebooks-do-not-support-this-operation","errorCode":null,"errorMessage":"Encrypted notebooks do not support this operation","messagePattern":"Encrypted notebooks do not support this operation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/blockial.go","lineNumber":340,"sourceCode":"\tif err != nil {\n\t\treturn\n\t}\n\n\ttx.writeTree(tree)\n\n\tIncSync()\n\tcache.PutBlockIALInBox(node.ID, tree.Box, parse.IAL2Map(node.KramdownIAL))\n\tpushBlockAttrs(oldAttrs, node)\n\treturn\n}\n\nfunc setNodeAttrs0(node *ast.Node, nameValues map[string]string, boxID string) (oldAttrs map[string]string, err error) {\n\t// 加密笔记本不支持书签和标签（依赖全局 SQLite 聚合，加密笔记本是孤岛）\n\tif IsEncryptedBox(boxID) && boxID != \"\" {\n\t\tfor name := range nameValues {\n\t\t\tswitch strings.ToLower(name) {\n\t\t\tcase \"bookmark\", \"tags\":\n\t\t\t\terr = errors.New(Conf.Language(313))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\toldAttrs = parse.IAL2Map(node.KramdownIAL)\n\tnewAttrsUnEsc := parse.IAL2MapUnEsc(node.KramdownIAL)\n\tfor name := range nameValues {\n\t\tif \"fold\" == strings.ToLower(name) {\n\t\t\tdelete(newAttrsUnEsc, \"heading-fold\")\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor name, value := range nameValues {\n\t\tvalue = util.RemoveInvalidRetainCtrl(value)\n\t\tvalue = strings.TrimSpace(value)\n\t\tlowerName := strings.ToLower(name)\n\t\t// 转换为小写再验证属性名","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/blockial.go#L322-L358","documentation":"In setNodeAttrs0 (the shared worker for SetBlockAttrs / BatchSetBlockAttrs), when the box is encrypted (IsEncryptedBox(boxID) && boxID != '') and one of the requested attribute names lower-cases to 'bookmark' or 'tags', it returns Conf.Language(313) — 'Encrypted notebooks do not support this operation'. The inline comment at blockial.go:335 states why: bookmarks and tags depend on the global SQLite aggregation, but an encrypted notebook is an isolated island, so those attributes cannot be indexed globally and are therefore rejected.","triggerScenarios":"POST /api/attr/setBlockAttrs or /api/attr/batchSetBlockAttrs including key 'bookmark' or 'tags' for a block that lives in an encrypted notebook. Reachable from the editor 'Bookmark'/'Add tag' affordances on such blocks.","commonSituations":"User encrypts a notebook then tries to bookmark or tag one of its blocks; a plugin applies the same attribute set across all notebooks regardless of encryption state; migrating a tagged doc into an encrypted box.","solutions":["Do not set 'bookmark' or 'tags' on blocks in encrypted notebooks — filter them out of the request.","If tagging/bookmarking is required, move the block to a non-encrypted notebook first.","In plugin/UI code, check the box encryption state (notebook conf) and disable the bookmark/tag control for encrypted boxes."],"exampleFix":"// before\nattrs := map[string]string{\"bookmark\": \"read\", \"custom-x\": \"y\"}\nmodel.SetBlockAttrs(id, attrs)\n\n// after: strip bookmark/tags for encrypted notebooks\nboxID := treenode.GetBlockTree(id).BoxID\nif model.IsEncryptedBox(boxID) {\n    delete(attrs, \"bookmark\")\n    delete(attrs, \"tags\")\n}\nmodel.SetBlockAttrs(id, attrs)","handlingStrategy":"validation","validationCode":"// Strip bookmark/tags when the target block lives in an encrypted notebook.\nbt := treenode.GetBlockTree(id)\nif bt != nil && model.IsEncryptedBox(bt.BoxID) {\n    delete(nameValues, \"bookmark\")\n    delete(nameValues, \"tags\")\n}","typeGuard":null,"tryCatchPattern":"// HTTP caller: detect the localized 'encrypted notebooks do not support' message and skip those keys.\nif (r.code === -1 && /encrypted notebook/i.test(r.msg)) {\n    delete attrs.bookmark; delete attrs.tags\n    r = await fetchSyncPost('/api/attr/setBlockAttrs', {id, attrs})\n}","preventionTips":["In UI/plugin code, disable bookmark/tag controls for blocks in encrypted notebooks.","Never broadcast the same attribute set to every notebook regardless of encryption state."],"tags":["encrypted-notebook","attrs","bookmark","tags","validation"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}