siyuan-note/siyuan · error

Unsupported template render mode

Error message

Unsupported template render mode

What it means

RenderTemplateRequest.RenderMode interprets the optional `mode` field of POST /api/template/render. When the decoder recorded that `mode` failed to unmarshal (invalidMode set), or when the string is not one of the two accepted values 'preview' or 'editorInsert', this error is returned. It guards against unknown render modes instead of silently falling back.

Solutions

  1. Use mode:"preview" to render for preview, or mode:"editorInsert" for inserting into the editor
  2. Omit `mode` and control behavior with the boolean `preview` field instead
  3. Fix the case/spelling — values are lowercase and case-sensitive

Example fix

// before
{"path":"...", "id":"...", "mode":"fullscreen"}
// after
{"path":"...", "id":"...", "mode":"preview"}
Defensive patterns

Strategy: type-guard

Validate before calling

if (p.mode !== undefined && !['preview','editorInsert'].includes(p.mode)) throw new Error('mode must be preview or editorInsert');

Type guard

const isRenderMode = (v) => v === 'preview' || v === 'editorInsert';

Try / catch

const res = await fetchPost('/api/template/render', payload); if (res.code !== 0 && res.msg === 'Unsupported template render mode') correctModeAndRetry();

Prevention

When it happens

Trigger: Calling /api/template/render with mode:"print", mode:"export", mode:123 (non-string), or any object/array for mode.

Common situations: A plugin written against an older API that supported other mode strings; a typo such as 'Preview' (case-sensitive); a client passing an enum index instead of the string name.

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@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/5abd812ca33bae8d. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/template_render.go:21

import (
	"encoding/json"
	"fmt"
	"io"
)

type RenderTemplateRequest struct {
	Path                                        string  `json:"path"`
	ID                                          string  `json:"id"`
	Mode                                        *string `json:"mode" api:"optional"`
	Preview                                     bool    `json:"preview" api:"optional,nullable"`
	Content                                     *string `json:"content" api:"optional,nonnullable"`
	invalidMode, invalidPreview, invalidContent bool
}

// RenderMode 在文档和路径校验后解释模式,显式模式优先于 preview。
func (r RenderTemplateRequest) RenderMode() (string, error) {
	if r.invalidMode {
		return "", fmt.Errorf("Unsupported template render mode")
	}
	if r.Mode != nil {
		if *r.Mode != "preview" && *r.Mode != "editorInsert" {
			return "", fmt.Errorf("Unsupported template render mode")
		}
		return *r.Mode, nil
	}
	if r.invalidPreview {
		return "", fmt.Errorf("Field [preview] should be of type [Boolean]")
	}
	if r.Preview {
		return "preview", nil
	}
	return "content", nil
}

func (r RenderTemplateRequest) PreviewSource(mode string) (*string, error) {
	if r.invalidContent || (r.Content != nil && mode != "preview") {

View on GitHub (pinned to 9f775e8a12)