siyuan-note/siyuan · error

unsupported template render mode [%s]

Error message

unsupported template render mode [%s]

What it means

renderTemplateSource only accepts three render modes: Content, Preview, and EditorInsert. Any other TemplateRenderMode value is rejected before any parsing happens. This is an argument validation error for an enum-like mode parameter.

Source

Thrown at kernel/model/template.go:751

}

func RenderTemplateWithMode(p, id string, mode TemplateRenderMode) (tree *parse.Tree, dom string,
	summary *TemplateDocTreePlanSummary, err error) {
	return renderTemplateSource(p, id, mode, nil)
}

// 编辑器预览使用未保存的源码,文件路径仅用于解析同包子模板。
func PreviewTemplateSource(p, id, content string) (tree *parse.Tree, dom string, summary *TemplateDocTreePlanSummary, err error) {
	if len(content) > maxTemplateSourceSize {
		return nil, "", nil, errors.New("template source is too large")
	}
	return renderTemplateSource(p, id, TemplateRenderModePreview, &content)
}

func renderTemplateSource(p, id string, mode TemplateRenderMode, content *string) (tree *parse.Tree, dom string,
	summary *TemplateDocTreePlanSummary, err error) {
	if TemplateRenderModeContent != mode && TemplateRenderModePreview != mode && TemplateRenderModeEditorInsert != mode {
		err = fmt.Errorf("unsupported template render mode [%s]", mode)
		return
	}
	preview := TemplateRenderModePreview == mode
	tree, err = LoadTreeByBlockID(id)
	if err != nil {
		return
	}
	sourceTree := tree

	node := treenode.GetNodeInTree(tree, id)
	if nil == node {
		err = ErrBlockNotFound
		return
	}
	block := sql.BuildBlockFromNode(node, tree)
	var md []byte
	if content == nil {
		md, err = os.ReadFile(p)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Pass one of the supported modes: TemplateRenderModeContent, TemplateRenderModePreview, or TemplateRenderModeEditorInsert
  2. If a new mode is needed, add it to the validation condition in renderTemplateSource (kernel/model/template.go:752)
  3. Initialize the mode variable explicitly instead of relying on the zero value

Example fix

// before
renderTemplateSource(p, id, "custom-mode", &content)
// after
renderTemplateSource(p, id, model.TemplateRenderModePreview, &content)
Defensive patterns

Strategy: validation

Validate before calling

switch mode {
case model.TemplateRenderModeContent, model.TemplateRenderModePreview, model.TemplateRenderModeEditorInsert:
    // ok
default:
    return errors.New("unsupported render mode")
}

Type guard

func validRenderMode(m model.TemplateRenderMode) bool {
    return m == model.TemplateRenderModeContent || m == model.TemplateRenderModePreview || m == model.TemplateRenderModeEditorInsert
}

Try / catch

tree, _, _, err := RenderTemplateWithMode(p, id, mode)
if err != nil && strings.Contains(err.Error(), "unsupported template render mode") {
    mode = model.TemplateRenderModeContent // retry with default
}

Prevention

When it happens

Trigger: Calling renderTemplateSource (directly or via a new wrapper) with a mode value other than TemplateRenderModeContent, TemplateRenderModePreview, or TemplateRenderModeEditorInsert — e.g. a newly added mode constant not yet whitelisted here, or an uninitialized/zero-value mode.

Common situations: Developer adds a new render mode constant and forgets to update the switch in renderTemplateSource; caller passes an empty string or stale mode value from config; test code using an invalid mode.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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