siyuan-note/siyuan · error

template document tree plan requires a parent content operat

Error message

template document tree plan requires a parent content operation

What it means

This error comes from validateTemplateDocTreeParentOperations, an internal consistency check on a template-document-tree plan transaction in SiYuan's kernel. A plan's transaction must not only pair every DoOperation with a matching UndoOperation, it must also include at least one parent-level content mutation (insert, delete, or update). If the transaction only contains non-content operations (foldHeading/unfoldHeading/setAttrs) or is empty of content mutations, the kernel rejects it because the plan cannot be applied as an undoable document change.

Source

Thrown at kernel/model/template_doc_tree.go:566

	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] {
			return errors.New("template document tree plan parent operations are not reversible")
		}
		undoOperations[key]--
	}
	if !hasContentMutation {
		return errors.New("template document tree plan requires a parent content operation")
	}
	for _, count := range undoOperations {
		if 0 != count {
			return errors.New("template document tree plan parent operations are not reversible")
		}
	}
	return nil
}

func transactionTargetsTemplateRoot(transaction *Transaction, rootID, boxID string) bool {
	matched := false
	for operationSetIndex, operations := range [][]*Operation{transaction.DoOperations, transaction.UndoOperations} {
		for _, operation := range operations {
			if nil == operation {
				continue
			}
			ids := []string{operation.ID}
			if "insert" == operation.Action {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Ensure the transaction attaching the plan includes at least one insert, delete, or update operation on a block in the target document
  2. Verify the code path building DoOperations/UndoOperations sets content-mutation actions, not only foldHeading/unfoldHeading/setAttrs
  3. Re-render the template plan so the plan contains real document changes, then re-attach
  4. If this appears without custom transaction code, report it as an internal invariant violation with reproduction steps

Example fix

// before: only non-content ops
txn.DoOperations = []*Operation{{Action: "setAttrs", ID: blockID}}
// after: include a content mutation
txn.DoOperations = []*Operation{{Action: "update", ID: blockID}, {Action: "setAttrs", ID: blockID}}
Defensive patterns

Strategy: validation

Validate before calling

hasContent := false
for _, op := range txn.DoOperations {
	if op.Action == "insert" || op.Action == "delete" || op.Action == "update" {
		hasContent = true
	}
}
if !hasContent {
	return errors.New("plan transaction needs at least one insert/delete/update parent operation")
}

Prevention

When it happens

Trigger: AttachTemplateDocTreePlans builds a transaction whose DoOperations/UndoOperations all use foldHeading, unfoldHeading, or setAttrs (no insert/delete/update on parent blocks), or a caller attaches a plan with an empty/operation-less transaction, so hasContentMutation stays false.

Common situations: Kernel-side or plugin-driven automation that applies a rendered template doc tree plan but pairs it only with attribute/fold state changes instead of actual block edits; internal invariant breakage after refactoring the plan/transaction builder; replaying a hand-crafted transaction missing content operations.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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