siyuan-note/siyuan · error
Encrypted notebooks do not support this operation
Error message
Encrypted notebooks do not support this operation
What it means
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.
Source
Thrown at kernel/model/blockial.go:340
if err != nil {
return
}
tx.writeTree(tree)
IncSync()
cache.PutBlockIALInBox(node.ID, tree.Box, parse.IAL2Map(node.KramdownIAL))
pushBlockAttrs(oldAttrs, node)
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 251596fc0d)
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.
Example fix
// before
attrs := map[string]string{"bookmark": "read", "custom-x": "y"}
model.SetBlockAttrs(id, attrs)
// after: strip bookmark/tags for encrypted notebooks
boxID := treenode.GetBlockTree(id).BoxID
if model.IsEncryptedBox(boxID) {
delete(attrs, "bookmark")
delete(attrs, "tags")
}
model.SetBlockAttrs(id, attrs) Defensive patterns
Strategy: validation
Validate before calling
// Strip bookmark/tags when the target block lives in an encrypted notebook.
bt := treenode.GetBlockTree(id)
if bt != nil && model.IsEncryptedBox(bt.BoxID) {
delete(nameValues, "bookmark")
delete(nameValues, "tags")
} Try / catch
// HTTP caller: detect the localized 'encrypted notebooks do not support' message and skip those keys.
if (r.code === -1 && /encrypted notebook/i.test(r.msg)) {
delete attrs.bookmark; delete attrs.tags
r = await fetchSyncPost('/api/attr/setBlockAttrs', {id, attrs})
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The attribute name can only contain lowercase English letter
- setting or removing [data-task] attribute is not allowed via
- Do not include Markdown syntax marker [%s]
- Bookmark cannot be empty
- Encrypted notebooks do not support this operation
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/32fa6a84e8998688.
Report an issue: GitHub.