gohugoio/hugo · error
html/template: pattern matches no files: %#q
Error message
html/template: pattern matches no files: %#q
What it means
Returned by parseGlob (backing ParseGlob and t.ParseGlob) when filepath.Glob succeeds but matches zero files. ParseGlob requires the pattern to match at least one file. The %#q quotes the offending pattern.
Source
Thrown at tpl/internal/go_templates/htmltemplate/template.go:476
// When parsing multiple files with the same name in different directories,
// the last one mentioned will be the one that results.
//
// ParseGlob returns an error if t or any associated template has already been executed.
func (t *Template) ParseGlob(pattern string) (*Template, error) {
return parseGlob(t, pattern)
}
// parseGlob is the implementation of the function and method ParseGlob.
func parseGlob(t *Template, pattern string) (*Template, error) {
if err := t.checkCanParse(); err != nil {
return nil, err
}
filenames, err := filepath.Glob(pattern)
if err != nil {
return nil, err
}
if len(filenames) == 0 {
return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern)
}
return parseFiles(t, readFileOS, filenames...)
}
// IsTrue reports whether the value is 'true', in the sense of not the zero of its type,
// and whether the value has a meaningful truth value. This is the definition of
// truth used by if and other such actions.
func IsTrue(val any) (truth, ok bool) {
return template.IsTrue(val)
}
// ParseFS is like [ParseFiles] or [ParseGlob] but reads from the file system fs
// instead of the host operating system's file system.
// It accepts a list of glob patterns.
// (Note that most file names serve as glob patterns matching only themselves.)
func ParseFS(fs fs.FS, patterns ...string) (*Template, error) {
return parseFS(nil, fs, patterns)
}View on GitHub (pinned to 52c9bd7908)
Solutions
- Print/log the absolute pattern and the resolved matches (filepath.Glob) to confirm the path.
- Ensure the working directory or use absolute paths / an embed.FS rooted at the binary.
- Correct the glob (e.g. add 'layouts/*.html') so it matches at least one file.
- Use ParseFS with go:embed so file resolution is independent of cwd.
Example fix
// before
t, err := template.ParseGlob("temlates/*.html") // typo, no match
// after
matches, _ := filepath.Glob("templates/*.html")
if len(matches) == 0 { return fmt.Errorf("no templates under %q", absDir) }
t, err := template.ParseGlob("templates/*.html") Defensive patterns
Strategy: validation
Validate before calling
func parseGlobSafe(pattern string) (*template.Template, error) {
matches, err := filepath.Glob(pattern)
if err != nil { return nil, err }
if len(matches) == 0 {
abs, _ := filepath.Abs(pattern)
return nil, fmt.Errorf("glob %q (abs %q) matched no files", pattern, abs)
}
return template.ParseGlob(pattern)
} Try / catch
t, err := template.ParseGlob(pattern)
if err != nil && strings.Contains(err.Error(), "pattern matches no files") {
cwd, _ := os.Getwd()
// fix cwd or switch to absolute/embed-based pattern, then retry
return template.ParseGlob(filepath.Join(absRoot, pattern))
} Prevention
- Resolve patterns to absolute paths or use embed.FS to avoid cwd issues.
- Log filepath.Glob results during init.
- In CI, assert the templates directory exists before running.
When it happens
Trigger: Calling template.ParseGlob(pattern) or t.ParseGlob(pattern) where pattern matches nothing under the current working directory (typo, wrong dir, missing files, wrong glob syntax that matches nothing).
Common situations: Running the binary from a different working directory than expected so relative globs miss; deploying without the templates directory; a typo in the glob (e.g. missing extension); CI that runs in a sparse checkout missing layout files.
Related errors
- template: pattern matches no files: %#q
- target path "{targetDir}" exists but is not a directory
- target path "{targetDir}" exists and is not empty
- {jekyllRoot} is not a directory
- abort: jekyll root contains neither posts nor drafts
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/70d7df4cecdac807.
Report an issue: GitHub.