siyuan-note/siyuan · critical
Encrypted notebooks do not support this operation
Error message
Encrypted notebooks do not support this operation
What it means
Thrown by Doc2Heading when the source document (srcTree) and target document (targetTree) reside in different cryptographic boundaries. IsSameCryptoBoundary(srcTree.Box, targetTree.Box) returns false. The code comment explains: Doc2Heading merges the content of srcTree and targetTree, and each encrypted notebook has its own Data Encryption Key (DEK). Merging across boundaries would cause ciphertext encrypted with one DEK to be interpreted under another, corrupting data. This is a critical data-integrity guard.
Source
Thrown at kernel/model/heading.go:218
logging.LogWarnf("remove empty dir [%s] failed: %s", subDir, removeErr)
}
}
if nil == treenode.GetBlockTree(targetID) {
// 目标块不存在时忽略处理
return
}
targetTree, _ := LoadTreeByBlockID(targetID)
if nil == targetTree {
// 目标块不存在时忽略处理
return
}
// 禁止跨加密边界:Doc2Heading 会合并 srcTree 和 targetTree 的内容,
// 不同加密笔记本各有独立 DEK,跨边界合并会导致密文用错 DEK 损坏数据
if !IsSameCryptoBoundary(srcTree.Box, targetTree.Box) {
err = errors.New(Conf.Language(313))
return
}
pivot := treenode.GetNodeInTree(targetTree, targetID)
if nil == pivot {
err = ErrBlockNotFound
return
}
// 生成文档历史 https://github.com/siyuan-note/siyuan/issues/14359
generateOpTypeHistory(srcTree, HistoryOpUpdate)
// 移动前先删除引用 https://github.com/siyuan-note/siyuan/issues/7819
sql.DeleteRefsTreeQueue(srcTree)
sql.DeleteRefsTreeQueue(targetTree)
if ast.NodeListItem == pivot.Type {
pivot = pivot.LastChildView on GitHub (pinned to 251596fc0d)
Solutions
- Keep Doc2Heading within the same notebook, or ensure both source and target are in non-encrypted notebooks.
- If you need content from an encrypted notebook in a plain notebook, export the content from the encrypted notebook and import it manually into the target.
- As an API client, verify IsSameCryptoBoundary(srcBox, targetBox) returns true before calling Doc2Heading.
Example fix
// before
await post('/api/filetree/doc2Heading', { srcID: docInEncryptedBox, targetID: docInPlainBox, after: true })
// after — only convert within the same crypto boundary
if (!isSameCryptoBoundary(srcBox, targetBox)) {
throw new Error('Cross-boundary Doc2Heading is blocked to prevent DEK mismatch corruption')
}
await post('/api/filetree/doc2Heading', { srcID, targetID, after: true }) Defensive patterns
Strategy: validation
Validate before calling
// Verify source and target are in the same crypto boundary before Doc2Heading
function isSameCryptoBoundary(srcBoxID, targetBoxID) {
const srcEncrypted = notebooks.find(nb => nb.id === srcBoxID)?.encrypted ?? false
const targetEncrypted = notebooks.find(nb => nb.id === targetBoxID)?.encrypted ?? false
// Same boundary: both non-encrypted, or same encrypted notebook
if (!srcEncrypted && !targetEncrypted) return true
return srcBoxID === targetBoxID
}
if (isSameCryptoBoundary(srcBox, targetBox)) {
await post('/api/filetree/doc2Heading', { srcID, targetID, after })
} Prevention
- Never perform Doc2Heading across different notebooks when either is encrypted.
- Keep Doc2Heading within the same notebook to avoid crypto boundary issues.
- Export and re-import content manually when cross-boundary transfer is needed.
When it happens
Trigger: Calling POST /api/filetree/doc2Heading where srcID is in one notebook and targetID is in a different notebook, and at least one of the two notebooks is encrypted (or both are encrypted with different DEKs). Even two different encrypted notebooks are different crypto boundaries. Also fires for encrypted-to-plain and plain-to-encrypted crosses.
Common situations: User tries to drag a document from an encrypted notebook into a document in a plain notebook (or vice versa); user tries to merge documents across two different encrypted notebooks; an API client performs cross-notebook Doc2Heading without checking encryption boundaries.
Related errors
- encrypted attribute view snapshot is missing notebook contex
- encrypted attribute view snapshot has no matching notebook [
- encrypted notebook attribute view snapshot is plaintext [%s]
- encrypted notebook metadata verification failed after write
- The top-level notebook document cannot be removed or moved
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/fd7d01a7fa3e817a.
Report an issue: GitHub.