siyuan-note/siyuan · error
template path is not a regular file or directory
Error message
template path is not a regular file or directory
What it means
checkTemplateFilePath verified the filesystem entry at the template path and found it is neither a regular file nor a directory (or it is a symlink). Only plain files and directories are allowed so template content is read predictably and symlinks cannot escape the templates root.
Source
Thrown at kernel/model/template_manage.go:112
return os.OpenRoot(filepath.Join(util.DataDir, "templates"))
}
// 除根目录外不接受符号链接,避免管理操作影响另一个模板包。
func checkTemplateFilePath(root *os.Root, p string) error {
if err := validateTemplateRelativePath(p, false); err != nil {
return err
}
parts := strings.Split(p, "/")
for i := range parts {
info, err := root.Lstat(strings.Join(parts[:i+1], "/"))
if errors.Is(err, os.ErrNotExist) && i == len(parts)-1 {
return nil
}
if err != nil {
return err
}
if info.Mode()&os.ModeSymlink != 0 || (!info.IsDir() && !info.Mode().IsRegular()) {
return errors.New("template path is not a regular file or directory")
}
}
return nil
}
func templateFileRevision(root *os.Root, p string) (string, error) {
info, err := root.Stat(p)
if err != nil {
return "", err
}
h := sha256.New()
if info.IsDir() {
err = fs.WalkDir(root.FS(), p, func(name string, entry fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
stat, statErr := entry.Info()
if statErr != nil {View on GitHub (pinned to 8641553a1f)
Solutions
- Replace the symlink or special file with a real regular file/directory
- Point the template path at an actual .md file or plain directory
- Remove unexpected special files from the templates directory
Example fix
// before $ ln -s /etc/passwd templates/evil.md // after: use a real file $ rm templates/evil.md $ cp real-template.md templates/evil.md
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Lstat(p)
if err != nil || info.Mode()&os.ModeSymlink != 0 || (!info.IsDir() && !info.Mode().IsRegular()) {
return errors.New("path must be a regular file or directory, not a symlink")
} Try / catch
if err := checkTemplateFilePath(root, p); err != nil {
return fmt.Errorf("template path unusable: %w", err)
} Prevention
- Do not place symlinks in the templates directory
- Create templates as plain .md files or plain directories
- Audit the templates dir for special files after syncing from other systems
When it happens
Trigger: DocSaveAsTemplateInDirectory or ManageTemplateFilePath checks os.Lstat/stat of the path and finds info.Mode()&os.ModeSymlink != 0 or a non-regular, non-directory mode (device, pipe, socket, irregular file).
Common situations: A symlink planted inside the templates directory pointing outside the workspace; named pipes or device files created by other tooling; a broken path that resolved to something unexpected.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- template directory contains a symbolic link
- asset path contains an unresolved symbolic link [%s]
- resolve assets directory [%s] failed: %w
- encrypted document is a symbolic link [%s]
- exporting symbolic links is not supported
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/1fd6e4f4de2e6bf6.
Report an issue: GitHub.