siyuan-note/siyuan · error

content template [ ] not found

Error message

content template [%s] not found

What it means

resolveDocContentTemplatePath checks that the resolved template file exists under <data>/templates/ using filelock.IsExist. When the file is missing, it reports which template path was not found. This is a plain existence check after path validation succeeded.

Solutions

  1. Verify the file exists at <data>/templates/<templatePath>; create it or correct the path/extension.
  2. List available templates (e.g. via the templates API) and use an exact existing path, watching case sensitivity.
  3. If the template was deleted, recreate it via the UI's Save as Template or the CreateTemplate API.

Example fix

// before
applyDocContentTemplate(boxID, "meeting-note.md", ...)
// after
// file exists at <data>/templates/meeting notes.md
applyDocContentTemplate(boxID, "meeting notes.md", ...)
Defensive patterns

Strategy: try-catch

Validate before calling

const fs = require("fs");
const exists = fs.existsSync(process.env.SIYUAN_DATA + "/templates/" + templatePath);

Try / catch

try {
  await applyDocContentTemplate(boxID, templatePath);
} catch (e) {
  if (String(e).includes("not found")) {
    // list templates and prompt user to pick an existing one
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling applyDocContentTemplate with a syntactically valid relative path ("notes/tpl.md") that does not exist in <data>/templates/, including wrong case on case-sensitive filesystems and typos in file extension.

Common situations: Template was renamed or deleted after a doc referenced it; template stored in a different notebook's assets; syncing where templates dir was excluded; typos like "templete.md" or missing ".md".

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/template.go:1228

	}
	av.BatchUpsertBlockRel(tree.Root.ChildrenByType(ast.NodeAttributeView))
	return nil
}

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 9f775e8a12)