{"record":{"id":"74772cb5edab2d12","repo":"gohugoio/hugo","slug":"invalid-filename","errorCode":null,"errorMessage":"invalid filename","messagePattern":"invalid filename","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/os/os.go","lineNumber":82,"sourceCode":"func (ns *Namespace) Getenv(key any) (string, error) {\n\tskey, err := cast.ToStringE(key)\n\tif err != nil {\n\t\treturn \"\", nil\n\t}\n\n\tif err = ns.deps.ExecHelper.Sec().CheckAllowedGetEnv(skey); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn _os.Getenv(skey), nil\n}\n\n// readFile reads the file named by filename in the given filesystem\n// and returns the contents as a string.\nfunc readFile(fs afero.Fs, filename string) (string, error) {\n\tfilename = filepath.Clean(filename)\n\tif filename == \"\" || filename == \".\" || filename == string(_os.PathSeparator) {\n\t\treturn \"\", errors.New(\"invalid filename\")\n\t}\n\n\tb, err := afero.ReadFile(fs, filename)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(b), nil\n}\n\n// ReadFile reads the file named by filename relative to the configured WorkingDir.\n// It returns the contents as a string.\n// There is an upper size limit set at 1 megabytes.\nfunc (ns *Namespace) ReadFile(i any) (string, error) {\n\ts, err := cast.ToStringE(i)\n\tif err != nil {\n\t\treturn \"\", err\n\t}","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/os/os.go#L64-L100","documentation":"Thrown by the internal readFile helper (used by os.ReadFile) when filepath.Clean reduces the filename to empty, \".\", or the OS path separator. This guards against reading the filesystem root or an empty path, which would be meaningless or unsafe.","triggerScenarios":"Calling {{ readFile \"\" }}, {{ readFile \".\" }}, or {{ readFile \"/\" }}. Also when a templated path collapses to one of these after filepath.Clean (e.g. a path of all slashes or dots).","commonSituations":"Passing an unset param; a computed path that strips down to nothing; user-supplied path variables that are empty by mistake.","solutions":["Validate the path is non-empty and not a root marker before calling: {{ with $path }}{{ if not (eq $path \"/\") }}{{ readFile $path }}{{ end }}{{ end }}.","Provide a sensible default file path.","Check the source of the path variable (e.g. .Params) to ensure it is set."],"exampleFix":"// before\n{{ readFile .Params.path }}\n// after\n{{ with .Params.path }}{{ readFile . }}{{ end }}","handlingStrategy":"validation","validationCode":"{{ with .Params.path }}{{ if and (ne . \"\") (ne . \"/\") (ne . \".\") }}{{ readFile . }}{{ end }}{{ end }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always check the path is non-empty and not a root marker before readFile.","Validate user-supplied path params.","Prefer resources.Get for asset files over os.ReadFile when possible."],"tags":["template","os","filesystem","validation","hugo"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}