siyuan-note/siyuan · error

template document tree plan contains an unsupported parent u

Error message

template document tree plan contains an unsupported parent undo operation

What it means

Each parent UndoOperation's Action must have an entry in the inverseActions table (insert, delete, update, foldHeading, unfoldHeading, setAttrs) and must have an empty RootID. This error means an undo operation uses an unsupported action type or is scoped to a root document, which the template plan machinery cannot reverse as part of the shared undo record.

Source

Thrown at kernel/model/template_doc_tree.go:542

	return true, nil
}

func validateTemplateDocTreeParentOperations(transaction *Transaction) error {
	inverseActions := map[string]string{
		"insert":        "delete",
		"delete":        "insert",
		"update":        "update",
		"foldHeading":   "unfoldHeading",
		"unfoldHeading": "foldHeading",
		"setAttrs":      "setAttrs",
	}
	undoOperations := map[string]int{}
	for _, operation := range transaction.UndoOperations {
		if nil == operation || "" == operation.ID {
			return errors.New("template document tree plan contains an invalid parent undo operation")
		}
		if _, supported := inverseActions[operation.Action]; !supported || "" != operation.RootID {
			return errors.New("template document tree plan contains an unsupported parent undo operation")
		}
		undoOperations[operation.Action+"\x00"+operation.ID]++
	}

	hasContentMutation := false
	for _, operation := range transaction.DoOperations {
		if nil == operation || "" == operation.ID {
			return errors.New("template document tree plan contains an invalid parent operation")
		}
		inverseAction, supported := inverseActions[operation.Action]
		if !supported || "" != operation.RootID {
			return errors.New("template document tree plan contains an unsupported parent operation")
		}
		if "insert" == operation.Action || "delete" == operation.Action || "update" == operation.Action {
			hasContentMutation = true
		}
		key := inverseAction + "\x00" + operation.ID
		if 1 > undoOperations[key] {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Restrict parent Do/Undo operations to actions in the inverse set: insert, delete, update, foldHeading, unfoldHeading, setAttrs
  2. Leave RootID empty ("") on all parent operations
  3. Split unrelated edits into their own transactions; the plan transaction may contain only the parent-document content mutation and its inverse
  4. Upgrade the kernel if a newly supported action is required — the allowlist is version-dependent

Example fix

// before
undoOps := []*Operation{{Action: "moveBlock", RootID: rootID, ID: blkID}}
// after
undoOps := []*Operation{{Action: "delete", ID: blkID}} // supported action, empty RootID
Defensive patterns

Strategy: validation

Validate before calling

supported := map[string]bool{"insert":true,"delete":true,"update":true,"foldHeading":true,"unfoldHeading":true,"setAttrs":true}; for _, op := range tx.UndoOperations { if !supported[op.Action] || op.RootID != "" { reject before submit } }

Try / catch

if err != nil && strings.Contains(err.Error(), "unsupported parent undo operation") { move the unsupported ops into a separate plain transaction and resubmit the plan transaction with only allowlisted ops }

Prevention

When it happens

Trigger: Including operations with actions like moveBlock/appendBlock/outline in the parent transaction's UndoOperations; setting operation.RootID on parent ops (RootID is reserved for the plan's generated child-document operations); auto-generated undo ops from other features mixed into the plan transaction.

Common situations: Integration code that copies an entire transaction's undo list (from unrelated edits) into a plan transaction; newer kernel actions not covered by the plan validator; misuse of RootID to scope parent edits.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/e4fcf92b8a38d8a5. Report an issue: GitHub.