{"record":{"id":"59ce1684485701f5","repo":"siyuan-note/siyuan","slug":"content-template-s-is-not-a-regular-file","errorCode":null,"errorMessage":"content template [%s] is not a regular file","messagePattern":"content template \\[(.+?)\\] is not a regular file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/template.go","lineNumber":730,"sourceCode":"\ttemplateRoot := filepath.Join(util.DataDir, \"templates\")\n\tabsPath := filepath.Join(templateRoot, cleanPath)\n\tif !gulu.File.IsSubPath(templateRoot, absPath) {\n\t\treturn \"\", errors.New(\"content template path is outside templates directory\")\n\t}\n\tif !filelock.IsExist(absPath) {\n\t\treturn \"\", fmt.Errorf(\"content template [%s] not found\", templatePath)\n\t}\n\trealRoot, err := filepath.EvalSymlinks(templateRoot)\n\tif nil != err {\n\t\treturn \"\", err\n\t}\n\trealPath, err := filepath.EvalSymlinks(absPath)\n\tif nil != err {\n\t\treturn \"\", err\n\t}\n\tinfo, err := os.Stat(realPath)\n\tif nil != err || !info.Mode().IsRegular() {\n\t\treturn \"\", fmt.Errorf(\"content template [%s] is not a regular file\", templatePath)\n\t}\n\tif !gulu.File.IsSubPath(realRoot, realPath) {\n\t\treturn \"\", errors.New(\"content template path is outside templates directory\")\n\t}\n\treturn realPath, nil\n}\n\n// CreateTemplate 在 <data>/templates/ 下创建模板文件。name 不含扩展名，content 为 markdown 文本。\n// overwrite=false 且文件已存在时返回 code=1（与 DocSaveAsTemplate 一致）。\nfunc CreateTemplate(name, content string, overwrite bool) (code int, err error) {\n\tname = util.FilterFileName(name) + \".md\"\n\tname = util.TruncateLenFileName(name)\n\tsavePath := filepath.Join(util.DataDir, \"templates\", name)\n\tif filelock.IsExist(savePath) {\n\t\tif !overwrite {\n\t\t\tcode = 1\n\t\t\treturn\n\t\t}","sourceCodeStart":712,"sourceCodeEnd":748,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/template.go#L712-L748","documentation":"Returned by resolveDocContentTemplatePath (template.go:730) when, after resolving symlinks with filepath.EvalSymlinks, os.Stat reports the target is NOT a regular file (info.Mode().IsRegular() is false, or stat itself errored). Guards against templates pointing at directories, devices, pipes, or sockets.","triggerScenarios":"The template path resolves to a directory, a named pipe, a device node, or a broken symlink target; os.Stat fails entirely (permission denied). EvalSymlinks succeeded (so the link chain resolves) but the terminal inode is not a regular file.","commonSituations":"A user accidentally points the content template at a directory (e.g. a templates subfolder rather than a .md file); a symlink points to a special file; filesystem corruption; permission issues preventing stat.","solutions":["Point the content template path at a specific .md FILE, not a directory.","If using a symlink, ensure the symlink target is a regular markdown file.","Check filesystem permissions on the target file; the SiYuan process must be able to stat it.","Replace any accidental directory/special-file path with a real template file."],"exampleFix":"// before — path is a directory\nresolveDocContentTemplatePath(\"subfolder\")\n\n// after — path is a regular file\nresolveDocContentTemplatePath(\"subfolder/tpl.md\")","handlingStrategy":"validation","validationCode":"import \"os\"\nimport \"path/filepath\"\n\nfunc templateIsRegularFile(p string) bool {\n    abs := filepath.Join(util.DataDir, \"templates\", filepath.Clean(filepath.FromSlash(p)))\n    real, err := filepath.EvalSymlinks(abs)\n    if err != nil { return false }\n    info, err := os.Stat(real)\n    if err != nil { return false }\n    return info.Mode().IsRegular()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Point content template paths at .md files, never directories or special files.","Ensure symlinks resolve to regular files.","Check filesystem permissions allow stat."],"tags":["template","filesystem","validation","security"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}