siyuan-note/siyuan · error
template document tree plan contains an invalid document sna
Error message
template document tree plan contains an invalid document snapshot
What it means
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.
Source
Thrown at kernel/model/template_doc_tree.go:503
if !ok || plan.id != planID || time.Now().After(plan.expiresAt) {
return false, errors.New("template document tree plan is invalid or has expired")
}
if !transactionTargetsTemplateRoot(target, plan.rootID, plan.boxID) {
return false, errors.New("template document tree plan does not match the edited document")
}
rootTree, loadErr := LoadTreeByBlockID(plan.rootID)
if nil != loadErr || nil == rootTree || rootTree.Box != plan.boxID || rootTree.Path != plan.rootPath ||
rootTree.HPath != plan.rootHPath {
return false, errors.New("the document used to render the template has changed")
}
target.templateDocTreeRootSnapshot = rootTree
box := Conf.Box(plan.boxID)
if nil == box {
return false, ErrBoxNotFound
}
for _, tree := range plan.trees {
if nil == tree || nil == tree.Root || tree.ID != tree.Root.ID || tree.Box != plan.boxID || box.Exist(tree.Path) {
return false, errors.New("template document tree plan contains an invalid document snapshot")
}
}
for _, tree := range plan.trees {
target.DoOperations = append(target.DoOperations, &Operation{
Action: "restoreCreatedDoc",
ID: tree.ID,
Tree: tree,
templateDocTreeRootID: plan.rootID,
})
}
for index := len(plan.trees) - 1; 0 <= index; index-- {
tree := plan.trees[index]
target.UndoOperations = append(target.UndoOperations, &Operation{
Action: "removeCreatedDoc",
ID: tree.ID,
Tree: tree,
templateDocTreeRootID: plan.rootID,View on GitHub (pinned to 8641553a1f)
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
Defensive patterns
Strategy: validation
Validate before calling
for _, t := range planChildPaths { if fileExists(filepath.Join(dataDir, boxID, t)) { resolve conflicts (rename/delete) before attaching the plan } } Try / catch
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 } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- template already exists, use --overwrite to replace: %s
- attribute view custom color [%d] is still in use by attribut
- attribute view [%s] view [%s] not found
- attribute view [%s] has no available view: %w
- attribute view [%s] visible view [%s] not found
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/1afa2c4ed9e926dc.
Report an issue: GitHub.