siyuan-note/siyuan · error

child template [%s] not found in the current template packag

Error message

child template [%s] not found in the current template package

What it means

After computing packageRoot (the template package directory) and joining the cleaned relative path, resolveTemplatePackageFile verifies the result stays inside the package and actually exists on disk. If the joined path escapes the package or filelock.IsExist returns false, this error reports the missing child template. Note the check uses the pre-EvalSymlinks path, so a symlink pointing to a nonexistent file also lands here.

Source

Thrown at kernel/model/template_doc_tree.go:416

	relativePath = strings.TrimPrefix(filepath.ToSlash(strings.TrimSpace(relativePath)), "/")
	cleanPath := filepath.Clean(filepath.FromSlash(relativePath))
	if "" == cleanPath || "." == cleanPath || filepath.IsAbs(cleanPath) || ".." == cleanPath ||
		strings.HasPrefix(cleanPath, ".."+string(os.PathSeparator)) {
		return "", errors.New("invalid child template path")
	}
	templatesRoot := filepath.Clean(filepath.Join(util.DataDir, "templates"))
	relRootTemplate, err := filepath.Rel(templatesRoot, filepath.Clean(rootTemplatePath))
	if nil != err || strings.HasPrefix(relRootTemplate, ".."+string(os.PathSeparator)) {
		return "", errors.New("template path is outside templates directory")
	}
	parts := strings.Split(filepath.ToSlash(relRootTemplate), "/")
	packageRoot := templatesRoot
	if 1 < len(parts) {
		packageRoot = filepath.Join(templatesRoot, parts[0])
	}
	absPath := filepath.Join(packageRoot, cleanPath)
	if !gulu.File.IsSubPath(packageRoot, absPath) || !filelock.IsExist(absPath) {
		return "", fmt.Errorf("child template [%s] not found in the current template package", relativePath)
	}
	realRoot, err := filepath.EvalSymlinks(packageRoot)
	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("child template [%s] is not a regular file", relativePath)
	}
	if !gulu.File.IsSubPath(realRoot, realPath) {
		return "", errors.New("child template path is outside the current template package")
	}
	return realPath, nil
}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Check the referenced child path in the template content and correct typos to match an existing file inside the package
  2. Create the missing child template file at data/templates/<package>/<referenced-path>
  3. Restore the deleted/renamed file (from sync history or backup) so the reference resolves
  4. Fix filename casing to match exactly, since Linux filesystems are case-sensitive

Example fix

// before (template content)
{{childTemplate "Header.tpl"}}
// after (file on disk is header.tpl)
{{childTemplate "header.tpl"}}
Defensive patterns

Strategy: validation

Validate before calling

// Go: confirm each referenced child template exists inside its package before rendering
pkgRoot := filepath.Join(util.DataDir, "templates", pkgName)
for _, ref := range childRefs {
    if _, err := os.Stat(filepath.Join(pkgRoot, filepath.FromSlash(ref))); err != nil {
        return fmt.Errorf("child template %q missing in package %s", ref, pkgName)
    }
}

Try / catch

path, err := resolveTemplatePackageFile(root, rel)
if err != nil {
    if strings.Contains(err.Error(), "not found in the current template package") {
        return fmt.Errorf("check reference %q — file missing or renamed", rel)
    }
    return err
}

Prevention

When it happens

Trigger: A template references a child template path that does not exist within its package root (data/templates/<first-path-segment>), e.g. {{childTemplate "missing.md"}} or a typo like 'header.tpl' vs 'headers/header.tpl'; or the file was deleted/moved after the package was created.

Common situations: Typos in child template references; renaming or deleting part of a template package while other templates still reference it; packages copied partially (missing subdirectory); case-sensitivity mismatch on Linux after editing on Windows/macOS.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/7860ac8213294cbc. Report an issue: GitHub.