{"record":{"id":"0d5bd12105af4ede","repo":"siyuan-note/siyuan","slug":"template-document-tree-parent-snapshot-is-invalid","errorCode":null,"errorMessage":"template document tree parent snapshot is invalid","messagePattern":"template document tree parent snapshot is invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/transaction.go","lineNumber":2624,"sourceCode":"\t\t\tif existingBox, exists := tx.restoredCreatedDocBoxes[operation.ID]; exists {\n\t\t\t\tif existingBox != operation.Tree.Box {\n\t\t\t\t\ttx.restoredCreatedDocBoxes[operation.ID] = \"\"\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttx.restoredCreatedDocBoxes[operation.ID] = operation.Tree.Box\n\t\t\t}\n\t\t}\n\t\tif (\"restoreCreatedDoc\" != operation.Action && \"removeCreatedDoc\" != operation.Action) ||\n\t\t\t\"\" == operation.templateDocTreeRootID || nil == operation.Tree {\n\t\t\tcontinue\n\t\t}\n\t\tif nil == tx.templateDocTreeRootSnapshot {\n\t\t\tsnapshot, loadErr := LoadTreeByBlockID(operation.templateDocTreeRootID)\n\t\t\tif nil != loadErr {\n\t\t\t\treturn fmt.Errorf(\"load template document tree parent snapshot failed: %w\", loadErr)\n\t\t\t}\n\t\t\tif nil == snapshot {\n\t\t\t\treturn errors.New(\"template document tree parent snapshot is invalid\")\n\t\t\t}\n\t\t\tif nil != expectedTemplateDocTreeRoot &&\n\t\t\t\t(expectedTemplateDocTreeRoot.ID != snapshot.ID || expectedTemplateDocTreeRoot.Box != snapshot.Box ||\n\t\t\t\t\texpectedTemplateDocTreeRoot.Path != snapshot.Path || expectedTemplateDocTreeRoot.HPath != snapshot.HPath) {\n\t\t\t\treturn errors.New(\"the document used to render the template has changed\")\n\t\t\t}\n\t\t\ttx.templateDocTreeRootSnapshot = snapshot\n\t\t}\n\t\tif nil == tx.templateDocTreeRootSnapshot || tx.templateDocTreeRootSnapshot.ID != operation.templateDocTreeRootID ||\n\t\t\ttx.templateDocTreeRootSnapshot.Box != operation.Tree.Box {\n\t\t\treturn errors.New(\"template document tree parent snapshot is invalid\")\n\t\t}\n\t}\n\ttx.listItemFoldCandidates = nil\n\ttx.listItemFoldCandidateIDs = map[string]struct{}{}\n\ttx.deletedAttrViewBlockIDs = map[string]map[string]struct{}{}\n\ttx.structureCheckNodes = map[*ast.Node]struct{}{}\n\ttx.crossTreeMoveRefRefreshes = nil","sourceCodeStart":2606,"sourceCodeEnd":2642,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/transaction.go#L2606-L2642","documentation":"When committing a transaction that creates a document from a template, the kernel loads the parent document tree snapshot referenced by templateDocTreeRootID. If the load call succeeds but returns a nil tree (the lookup found nothing while reporting no error), the kernel treats the parent reference as invalid and fails the commit with this error.","triggerScenarios":"A doRestoreCreatedDoc operation's templateDocTreeRootID points to a block/tree that LoadTreeByBlockID cannot resolve (returns nil, nil) — typically because the referenced document or block no longer exists in the index.","commonSituations":"The parent document was deleted or its root block changed after the template render but before commit; an out-of-sync index reports no tree for a valid ID; concurrent sync removed the document mid-transaction.","solutions":["Refresh/reindex the notebook so the index agrees with the .sy files on disk, then retry the operation","Re-create the document from the template in the current UI state so a live parent document reference is used","Check that the parent document referenced still exists and has not been deleted by another client or sync"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const doc = await fetchPost('/api/filetree/getDoc', {id: parentRootId});\nif (doc.code !== 0 || !doc.data) throw new Error('parent snapshot unavailable');","typeGuard":null,"tryCatchPattern":"try {\n  await commitTemplateCreation(tx);\n} catch (e) {\n  if (String(e.message).includes('parent snapshot is invalid')) {\n    await reindexNotebook(boxId);\n    await commitTemplateCreation(tx); // retry after index refresh\n  } else { throw e; }\n}","preventionTips":["Avoid deleting the template's parent document between render and commit","Let sync finish before performing template-based document creation","Refresh the kernel index if lookups return empty for known-existing documents"],"tags":["transaction","templates","invariant"],"backgroundTag":"internal-invariant-violation","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"}