siyuan-note/siyuan · error

Field [preview] should be of type [Boolean]

Error message

Field [preview] should be of type [Boolean]

What it means

The template render API accepts a `preview` field that must be a JSON boolean. When the request payload carries `preview` with a non-boolean value (string, number, null, object), the request decoder flags it invalid and RenderMode refuses to derive a mode, returning this type error instead of proceeding. It exists to enforce strict request schema typing at the apicontract boundary.

Solutions

  1. Change the request so preview is an unquoted JSON boolean: true or false
  2. Remove the preview field entirely (the API then falls back to mode "content")
  3. Check the client serialization layer so booleans are not stringified before fetch/post
  4. If the value comes from user config, coerce with a strict parser that rejects anything but 'true'/'false' before sending

Example fix

// before
POST body: {"preview": "true"}
// after
POST body: {"preview": true}
Defensive patterns

Strategy: validation

Validate before calling

function isValidPreviewPayload(body) {
  return body.preview === undefined || typeof body.preview === "boolean";
}
if (!isValidPreviewPayload(payload)) throw new Error("preview must be a JSON boolean");

Type guard

const isBoolean = (v) => typeof v === "boolean";

Prevention

When it happens

Trigger: Calling the template render endpoint with body {"preview": "true"} or {"preview": 1} instead of a real JSON boolean; clients serializing booleans as strings; older clients sending truthy numbers.

Common situations: Hand-written curl/JSON bodies quoting the boolean; dynamically built payloads in JS where a string 'true' leaks in from a form field; plugin code passing config strings directly into the request.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/91704c8e6a39e356. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/template_render.go:30

	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") {
		return nil, fmt.Errorf("Source content is only supported for template preview")
	}
	return r.Content, nil
}

type TemplatePlanNode struct {
	ID       string `json:"id"`
	Title    string `json:"title"`
	ParentID string `json:"parentID"`

View on GitHub (pinned to 9f775e8a12)