{"record":{"id":"2950596a0d500c38","repo":"siyuan-note/siyuan","slug":"template-document-tree-plan-does-not-match-the-edi","errorCode":null,"errorMessage":"template document tree plan does not match the edited document","messagePattern":"template document tree plan does not match the edited document","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_doc_tree.go","lineNumber":489,"sourceCode":"\t}\n\tfor _, operation := range append(append([]*Operation{}, target.DoOperations...), target.UndoOperations...) {\n\t\tif nil != operation && (\"restoreCreatedDoc\" == operation.Action || \"removeCreatedDoc\" == operation.Action) {\n\t\t\treturn false, errors.New(\"template document tree transaction contains a reserved operation\")\n\t\t}\n\t}\n\n\tplanID := target.TemplateDocTreePlanID\n\ttarget.TemplateDocTreePlanID = \"\"\n\tvalue, loaded := templateDocTreePlans.LoadAndDelete(planID)\n\tif !loaded {\n\t\treturn false, errors.New(\"template document tree plan is missing or has expired\")\n\t}\n\tplan, ok := value.(*templateDocTreePlan)\n\tif !ok || plan.id != planID || time.Now().After(plan.expiresAt) {\n\t\treturn false, errors.New(\"template document tree plan is invalid or has expired\")\n\t}\n\tif !transactionTargetsTemplateRoot(target, plan.rootID, plan.boxID) {\n\t\treturn false, errors.New(\"template document tree plan does not match the edited document\")\n\t}\n\trootTree, loadErr := LoadTreeByBlockID(plan.rootID)\n\tif nil != loadErr || nil == rootTree || rootTree.Box != plan.boxID || rootTree.Path != plan.rootPath ||\n\t\trootTree.HPath != plan.rootHPath {\n\t\treturn false, errors.New(\"the document used to render the template has changed\")\n\t}\n\ttarget.templateDocTreeRootSnapshot = rootTree\n\tbox := Conf.Box(plan.boxID)\n\tif nil == box {\n\t\treturn false, ErrBoxNotFound\n\t}\n\tfor _, tree := range plan.trees {\n\t\tif nil == tree || nil == tree.Root || tree.ID != tree.Root.ID || tree.Box != plan.boxID || box.Exist(tree.Path) {\n\t\t\treturn false, errors.New(\"template document tree plan contains an invalid document snapshot\")\n\t\t}\n\t}\n\n\tfor _, tree := range plan.trees {","sourceCodeStart":471,"sourceCodeEnd":507,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/template_doc_tree.go#L471-L507","documentation":"transactionTargetsTemplateRoot verifies that the transaction's Do/Undo operations actually target the template root document recorded in the plan (plan.rootID/plan.boxID). This error means the plan was rendered from a different document than the one the transaction edits — the plan and transaction are mismatched.","triggerScenarios":"Client renders a plan against document A but submits the transaction whose parent operations edit document B; a transaction batch that mixes documents; using a plan ID captured from another editor tab open on a different document.","commonSituations":"Two editor tabs open, template rendered in tab 1 but transaction sent from tab 2; a script that renders once and applies to several documents; copy-pasted integration code reusing a plan across boxes/notebooks.","solutions":["Render the plan from the same document (rootID and notebook) that the transaction's parent operations modify","Ensure the transaction contains at least one operation whose ID (or insert ParentID/PreviousID/NextID) equals plan.rootID in the matching box","Send one plan per transaction and never share plan IDs across documents","Re-render the plan if the user switched documents between rendering and applying"],"exampleFix":"// before\ntx.DoOperations = operationsFor(docB) // docB != plan.rootID\ntx.TemplateDocTreePlanID = planIDFrom(docA)\n// after\ntx.DoOperations = operationsFor(planRootDoc) // parent ops must target the plan's root document\ntx.TemplateDocTreePlanID = planIDFrom(planRootDoc)","handlingStrategy":"validation","validationCode":"for _, op := range append(tx.DoOperations, tx.UndoOperations...) { if op.ID != planRootID && op.ParentID != planRootID { abort: plan/transaction document mismatch } }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"does not match the edited document\") { re-render the plan for the current document and rebuild the transaction }","preventionTips":["Always render the plan from the same document the transaction edits","Bind plan ID to the editor tab/document and discard it on document switch","Never share plan IDs across notebooks or documents","Keep one plan per transaction"],"tags":["go","transaction","template","document-mismatch"],"backgroundTag":"invalid-argument-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}