{"id":"d76ab5cf557e05e7","repo":"labstack/echo","slug":"echo-static-middleware-directory-list-template-par","errorCode":null,"errorMessage":"echo static middleware directory list template parsing error: %w","messagePattern":"echo static middleware directory list template parsing error: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/static.go","lineNumber":197,"sourceCode":"\tif config.Root == \"\" {\n\t\tconfig.Root = \".\" // For security we want to restrict to CWD.\n\t} else {\n\t\tconfig.Root = path.Clean(config.Root) // fs.Open is very picky about ``, `.`, `..` in paths, so remove some of them up.\n\t}\n\n\tif config.Skipper == nil {\n\t\tconfig.Skipper = DefaultStaticConfig.Skipper\n\t}\n\tif config.Index == \"\" {\n\t\tconfig.Index = DefaultStaticConfig.Index\n\t}\n\tif config.DirectoryListTemplate == \"\" {\n\t\tconfig.DirectoryListTemplate = directoryListHTMLTemplate\n\t}\n\n\tdirListTemplate, tErr := template.New(\"index\").Parse(config.DirectoryListTemplate)\n\tif tErr != nil {\n\t\treturn nil, fmt.Errorf(\"echo static middleware directory list template parsing error: %w\", tErr)\n\t}\n\n\tvar once *sync.Once\n\tvar fsErr error\n\tcurrentFS := config.Filesystem\n\tif config.Filesystem == nil {\n\t\tonce = &sync.Once{}\n\t} else if config.Root != \".\" {\n\t\ttmpFs, fErr := fs.Sub(config.Filesystem, path.Join(\".\", config.Root))\n\t\tif fErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"static middleware failed to create sub-filesystem from config.Root, error: %w\", fErr)\n\t\t}\n\t\tcurrentFS = tmpFs\n\t}\n\n\treturn func(next echo.HandlerFunc) echo.HandlerFunc {\n\t\treturn func(c *echo.Context) (err error) {\n\t\t\tif config.Skipper(c) {","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/middleware/static.go#L179-L215","documentation":"Returned by StaticConfig.ToMiddleware() when text/template.Parse fails on config.DirectoryListTemplate. The default template is the built-in directoryListHTMLTemplate; providing a custom template with invalid Go template syntax (unclosed actions, bad pipelines, undefined functions) causes this startup-time error.","triggerScenarios":"Setting StaticConfig.DirectoryListTemplate to a string containing malformed template syntax such as '{{ .Name' (unclosed), '{{ foo . }}' (undefined function), or invalid pipeline operators. Returned before any request is served.","commonSituations":"Customizing the directory listing UI with a hand-written template that has a typo; upgrading Echo and reusing an old template referencing fields that changed; copy-pasting HTML with literal '{{' that the template engine interprets as actions.","solutions":["Validate the custom DirectoryListTemplate with text/template in isolation (template.New(...).Parse(...)) before passing it to StaticWithConfig.","Ensure the template only references the provided fields: .Name and .Files (a slice of structs with Name, Dir, Size).","Escape literal curly braces in HTML (use '{{\"{{\"}}') if you need literal mustaches.","Leave DirectoryListTemplate empty to use the built-in default template."],"exampleFix":"// before\ntmpl := `<ul>{{ range .Files}<li>{{.Name}}</li>{{end}}</ul>` // missing '}'\n// after\ntmpl := `<ul>{{ range .Files }}<li>{{.Name}}</li>{{end}}</ul>`","handlingStrategy":"validation","validationCode":"// Parse the template before passing it to StaticWithConfig.\nfunc validateDirTemplate(tmpl string) error {\n    _, err := template.New(\"index\").Parse(tmpl)\n    return err\n}\n\nif err := validateDirTemplate(cfg.DirectoryListTemplate); err != nil {\n    return fmt.Errorf(\"bad directory list template: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always parse custom templates in isolation first to surface syntax errors clearly.","Reference only the documented fields (.Name, .Files[].Name/.Dir/.Size).","Omit DirectoryListTemplate to use the built-in default."],"tags":["config","static","template","startup"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}