siyuan-note/siyuan · error
content template [%s] not found
Error message
content template [%s] not found
What it means
Returned by resolveDocContentTemplatePath (template.go:718) when the resolved absolute path does not exist on disk (filelock.IsExist(absPath) returns false). The path passed all structural and sub-path guards but no file is present at that location.
Source
Thrown at kernel/model/template.go:718
}
tree.Root.SetIALAttr("updated", util.CurrentTimeSecondsStr())
return indexWriteTreeUpsertQueue(tree)
}
func resolveDocContentTemplatePath(templatePath string) (string, error) {
templatePath = strings.TrimPrefix(filepath.ToSlash(strings.TrimSpace(templatePath)), "/")
cleanPath := filepath.Clean(filepath.FromSlash(templatePath))
if "" == cleanPath || "." == cleanPath || filepath.IsAbs(cleanPath) || ".." == cleanPath ||
strings.HasPrefix(cleanPath, ".."+string(os.PathSeparator)) {
return "", errors.New("invalid content template path")
}
templateRoot := filepath.Join(util.DataDir, "templates")
absPath := filepath.Join(templateRoot, cleanPath)
if !gulu.File.IsSubPath(templateRoot, absPath) {
return "", errors.New("content template path is outside templates directory")
}
if !filelock.IsExist(absPath) {
return "", fmt.Errorf("content template [%s] not found", templatePath)
}
realRoot, err := filepath.EvalSymlinks(templateRoot)
if nil != err {
return "", err
}
realPath, err := filepath.EvalSymlinks(absPath)
if nil != err {
return "", err
}
info, err := os.Stat(realPath)
if nil != err || !info.Mode().IsRegular() {
return "", fmt.Errorf("content template [%s] is not a regular file", templatePath)
}
if !gulu.File.IsSubPath(realRoot, realPath) {
return "", errors.New("content template path is outside templates directory")
}
return realPath, nil
}View on GitHub (pinned to 251596fc0d)
Solutions
- Confirm the template file exists under <data>/templates/ with the exact name and extension referenced.
- On case-sensitive filesystems (Linux), match the filename casing exactly.
- If the template was renamed, update the document's content-template path to the new name.
- Re-download/recreate the template if a sync operation removed it.
Example fix
// before — file missing or wrong case
resolveDocContentTemplatePath("Diary.md") // actual file is diary.md
// after — exact filename
resolveDocContentTemplatePath("diary.md") Defensive patterns
Strategy: validation
Validate before calling
import "path/filepath"
import "filelock"
func templateFileExists(p string) bool {
abs := filepath.Join(util.DataDir, "templates", filepath.Clean(filepath.FromSlash(p)))
return filelock.IsExist(abs)
} Prevention
- Confirm the template file exists with exact casing before referencing it.
- On case-sensitive filesystems, match the filename case precisely.
- After sync operations, verify referenced template files survived.
When it happens
Trigger: A document references a content template file that was deleted, moved, or never created; the templates directory was migrated/renamed; the path has a typo or wrong extension; the workspace data dir changed.
Common situations: Template file deleted by the user or a sync conflict; referencing a template by a name that does not match the actual file; workspace moved so <data>/templates/ no longer contains the expected file; case-sensitivity mismatch on case-sensitive filesystems.
Related errors
- Obsidian Vault is unreadable: read Vault root: %v
- content template [%s] is not a regular file
- import path is not sub path of import dir
- notebook [%s] not found
- notebook not found: %s
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/a2ea7a4d783803a2.
Report an issue: GitHub.