{"record":{"id":"5abd812ca33bae8d","repo":"siyuan-note/siyuan","slug":"unsupported-template-render-mode","errorCode":null,"errorMessage":"Unsupported template render mode","messagePattern":"Unsupported template render mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/template_render.go","lineNumber":21,"sourceCode":"import (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n)\n\ntype RenderTemplateRequest struct {\n\tPath                                        string  `json:\"path\"`\n\tID                                          string  `json:\"id\"`\n\tMode                                        *string `json:\"mode\" api:\"optional\"`\n\tPreview                                     bool    `json:\"preview\" api:\"optional,nullable\"`\n\tContent                                     *string `json:\"content\" api:\"optional,nonnullable\"`\n\tinvalidMode, invalidPreview, invalidContent bool\n}\n\n// RenderMode 在文档和路径校验后解释模式，显式模式优先于 preview。\nfunc (r RenderTemplateRequest) RenderMode() (string, error) {\n\tif r.invalidMode {\n\t\treturn \"\", fmt.Errorf(\"Unsupported template render mode\")\n\t}\n\tif r.Mode != nil {\n\t\tif *r.Mode != \"preview\" && *r.Mode != \"editorInsert\" {\n\t\t\treturn \"\", fmt.Errorf(\"Unsupported template render mode\")\n\t\t}\n\t\treturn *r.Mode, nil\n\t}\n\tif r.invalidPreview {\n\t\treturn \"\", fmt.Errorf(\"Field [preview] should be of type [Boolean]\")\n\t}\n\tif r.Preview {\n\t\treturn \"preview\", nil\n\t}\n\treturn \"content\", nil\n}\n\nfunc (r RenderTemplateRequest) PreviewSource(mode string) (*string, error) {\n\tif r.invalidContent || (r.Content != nil && mode != \"preview\") {","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/template_render.go#L3-L39","documentation":"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.","triggerScenarios":"Calling /api/template/render with mode:\"print\", mode:\"export\", mode:123 (non-string), or any object/array for mode.","commonSituations":"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.","solutions":["Use mode:\"preview\" to render for preview, or mode:\"editorInsert\" for inserting into the editor","Omit `mode` and control behavior with the boolean `preview` field instead","Fix the case/spelling — values are lowercase and case-sensitive"],"exampleFix":"// before\n{\"path\":\"...\", \"id\":\"...\", \"mode\":\"fullscreen\"}\n// after\n{\"path\":\"...\", \"id\":\"...\", \"mode\":\"preview\"}","handlingStrategy":"type-guard","validationCode":"if (p.mode !== undefined && !['preview','editorInsert'].includes(p.mode)) throw new Error('mode must be preview or editorInsert');","typeGuard":"const isRenderMode = (v) => v === 'preview' || v === 'editorInsert';","tryCatchPattern":"const res = await fetchPost('/api/template/render', payload); if (res.code !== 0 && res.msg === 'Unsupported template render mode') correctModeAndRetry();","preventionTips":["Only send the two documented lowercase mode strings","Prefer the preview boolean over mode for simple cases","Watch for case-sensitive typos like 'Preview'"],"tags":["template","validation","enum","http-api"],"backgroundTag":"invalid-enum-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}