siyuan-note/siyuan · error

renderDocRef is only available when manually inserting or pr

Error message

renderDocRef is only available when manually inserting or previewing a template

What it means

renderDocRef is a template action that queries documents created/planned in the current template doc-tree session; it requires the collector to be enabled, which only happens during manual template insertion or template preview. When called with no active collector, it returns this error. This blocks renderDocRef in contexts where there is no doc tree to query.

Source

Thrown at kernel/model/template_doc_tree.go:243

		return "", fmt.Errorf("createDocTree exceeds the maximum document count of %d", maxTemplateDocTreeDocs)
	}
	collector.bindNodes(nodes, collector.rootID, collector.rootPath, collector.rootHPath)
	collector.nodes = append(collector.nodes, nodes...)
	return "", nil
}

func (collector *templateDocTreeCollector) bindNodes(nodes []*TemplateDocTreeNode, parentID, parentPath, parentHPath string) {
	for _, node := range nodes {
		node.ParentID = parentID
		node.path = strings.TrimSuffix(parentPath, ".sy") + "/" + node.ID + ".sy"
		node.HPath = path.Join(parentHPath, node.Title)
		collector.bindNodes(node.Children, node.ID, node.path, node.HPath)
	}
}

func (collector *templateDocTreeCollector) renderDocRef(mode string, value any) (any, error) {
	if !collector.enabled {
		return nil, errors.New("renderDocRef is only available when manually inserting or previewing a template")
	}
	switch mode {
	case "children":
		id, ok := value.(string)
		if !ok {
			return nil, errors.New("renderDocRef children target must be a document ID")
		}
		if collector.rootID == id {
			return collector.nodes, nil
		}
		for _, node := range flattenTemplateDocTreeNodes0(collector.nodes) {
			if node.ID == id {
				return node.Children, nil
			}
		}
		return []*TemplateDocTreeNode{}, nil
	case "path":
		hPath, ok := value.(string)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Use renderDocRef only in templates inserted manually or rendered in preview mode.
  2. Replace renderDocRef usage with static block references when the target document is known ahead of time.
  3. In test harnesses, enable the collector (enabled=true) and populate nodes before rendering.

Example fix

// before (fragment used in normal content render)
renderDocRef("children", "20240101120000-abc")
// after
use it only inside a template inserted via the editor, or hard-code ((block ref))s
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the collector is enabled before rendering templates that use renderDocRef
const usable = renderMode === "editorInsert" || renderMode === "preview";

Try / catch

try {
  renderTemplate(src);
} catch (e) {
  if (String(e).includes("renderDocRef is only available")) {
    // re-render with preview/insert enabled or use static refs
  }
}

Prevention

When it happens

Trigger: Using renderDocRef in a template rendered outside insertion/preview (e.g. included via another rendering path, or during template listing/content render where the collector is disabled).

Common situations: Moving a template that worked on insert into a passive render context; a shared template fragment using renderDocRef that is included both in previews and in other renders; tests invoking the render function without enabling the collector.

Related errors


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