{"record":{"id":"be9fbc0f4cf74a2c","repo":"siyuan-note/siyuan","slug":"cannot-swap-blocks-across-encrypted-notebook-boundaries","errorCode":null,"errorMessage":"cannot swap blocks across encrypted notebook boundaries","messagePattern":"cannot swap blocks across encrypted notebook boundaries","errorType":"exception","errorClass":"TxErr","httpStatus":null,"severity":"error","filePath":"kernel/model/transaction_block_swap.go","lineNumber":64,"sourceCode":"\t}\n\tdata, err := json.Marshal(operation.Data)\n\tif err != nil {\n\t\treturn fail(err)\n\t}\n\tvar options blockSwapOptions\n\tif err = json.Unmarshal(data, &options); err != nil || options.IncludeChildren == nil || options.OriginalToEmbed == nil {\n\t\treturn fail(errors.New(\"invalid block swap options\"))\n\t}\n\trefTree, err := tx.loadTree(operation.ID)\n\tif err != nil {\n\t\treturn fail(err)\n\t}\n\tdefTree, err := tx.loadTree(operation.BlockID)\n\tif err != nil {\n\t\treturn fail(err)\n\t}\n\tif !IsSameCryptoBoundary(refTree.Box, defTree.Box) {\n\t\treturn fail(errors.New(\"cannot swap blocks across encrypted notebook boundaries\"))\n\t}\n\tref := treenode.GetNodeInTree(refTree, operation.ID)\n\tdef := treenode.GetNodeInTree(defTree, operation.BlockID)\n\tif err = validateBlockSwap(ref, def, *options.IncludeChildren); err != nil {\n\t\treturn fail(err)\n\t}\n\ttrees := []*parse.Tree{refTree}\n\tif refTree.ID != defTree.ID {\n\t\ttrees = append(trees, defTree)\n\t}\n\tbefore := captureBlockSwapFragments(trees)\n\ttx.saveBlockSwapOriginalTrees(trees)\n\tswapBlockRefNodes(ref, def, operation.BlockID, *options.IncludeChildren, *options.OriginalToEmbed)\n\tafter := captureBlockSwapFragments(trees)\n\tstate := newBlockSwapState(before, after)\n\toperation.blockSwapState = state\n\toperation.RetData = state.rootIDs\n\ttx.UndoOperations = []*Operation{{Action: \"swapBlockRef\", ID: operation.ID, BlockID: operation.BlockID,","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/transaction_block_swap.go#L46-L82","documentation":"The two blocks being swapped live in different notebooks, and those notebooks sit on opposite sides of the encrypted-notebook crypto boundary (IsSameCryptoBoundary returns false). Swapping fragments across such a boundary is refused to avoid writing plaintext-encrypted content between differently encrypted data stores. This is an intentional data-safety guard.","triggerScenarios":"Calling a swap-block-ref transaction where operation.ID (ref block) and operation.BlockID (definition block) belong to notebooks with incompatible crypto boundaries, e.g. one encrypted notebook and one plain notebook.","commonSituations":"Dragging a block from an encrypted notebook into a regular one and swapping block references; scripts automating cross-notebook block moves; synced workspaces mixing encrypted and unencrypted notebooks.","solutions":["Swap blocks only within the same notebook, or within notebooks sharing the same crypto boundary","Move one of the blocks into the other notebook first (as a normal move), then perform the swap","Check notebook encryption settings and align them if cross-notebook swaps are required"],"exampleFix":"// before\n{\"action\":\"swap-block-ref\",\"id\":\"20240101111111-abc (boxA: encrypted)\",\"blockID\":\"20240101222222-xyz (boxB: plain)\"}\n// after\n// move the block into the same notebook first, then:\n{\"action\":\"swap-block-ref\",\"id\":\"20240101111111-abc (boxA)\",\"blockID\":\"20240101333333-def (boxA)\"}","handlingStrategy":"validation","validationCode":"const refBox = getBoxOfBlock(op.id), defBox = getBoxOfBlock(op.blockID);\nif (refBox !== defBox && notebookEncryptionMode(refBox) !== notebookEncryptionMode(defBox)) {\n  throw new Error('cross encrypted notebook boundary swap is not allowed');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Swap only within the same notebook unless all involved notebooks share the same crypto boundary","Check notebook encryption configuration before automated cross-notebook operations"],"tags":["encryption","notebook","block-swap","security"],"backgroundTag":"incompatible-source-type","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}