{"record":{"id":"1afa2c4ed9e926dc","repo":"siyuan-note/siyuan","slug":"template-document-tree-plan-contains-an-invalid-do","errorCode":null,"errorMessage":"template document tree plan contains an invalid document snapshot","messagePattern":"template document tree plan contains an invalid document snapshot","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template_doc_tree.go","lineNumber":503,"sourceCode":"\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 {\n\t\ttarget.DoOperations = append(target.DoOperations, &Operation{\n\t\t\tAction:                \"restoreCreatedDoc\",\n\t\t\tID:                    tree.ID,\n\t\t\tTree:                  tree,\n\t\t\ttemplateDocTreeRootID: plan.rootID,\n\t\t})\n\t}\n\tfor index := len(plan.trees) - 1; 0 <= index; index-- {\n\t\ttree := plan.trees[index]\n\t\ttarget.UndoOperations = append(target.UndoOperations, &Operation{\n\t\t\tAction:                \"removeCreatedDoc\",\n\t\t\tID:                    tree.ID,\n\t\t\tTree:                  tree,\n\t\t\ttemplateDocTreeRootID: plan.rootID,","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/template_doc_tree.go#L485-L521","documentation":"Every child document tree stored in the plan is validated before its restoreCreatedDoc operation is appended: it must be non-nil with a valid root whose ID matches, belong to the plan's notebook, and its on-disk path must NOT already exist (box.Exist). This error means a snapshot in the plan is corrupt or a child document file already exists at the planned path, so restoring would clash with an existing document.","triggerScenarios":"A child document with the same path was created (by sync, another client, or a previous partially-applied plan) after the plan was rendered; the plan's in-memory trees were corrupted; a plan ID is reused against a workspace where the target files exist.","commonSituations":"Applying the same template twice without re-rendering; sync creating the target documents before the transaction lands; restoring a workspace snapshot while a stale plan is in flight.","solutions":["Re-render the plan so the snapshots reflect current disk state, then apply once","Delete or rename the conflicting existing documents at the planned child paths, or let the plan pick new IDs","Apply each plan exactly once; a partially applied plan leaves files that make re-runs fail","Check sync: ensure no other client created the same documents concurrently"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for _, t := range planChildPaths { if fileExists(filepath.Join(dataDir, boxID, t)) { resolve conflicts (rename/delete) before attaching the plan } }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid document snapshot\") { re-render the plan; if a child path exists, delete or rename it first, then apply once }","preventionTips":["Apply each plan exactly once; re-render for repeat applications","Check that target child document paths are free before applying","Coordinate sync so concurrent clients do not create the same documents","Clean up after partially applied plans before retrying"],"tags":["go","template","document-exists","conflict"],"backgroundTag":"file-already-exists","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}