{"record":{"id":"a4504ec0b4fc5d3b","repo":"kataras/iris","slug":"err-a4504e","errorCode":null,"errorMessage":"err","messagePattern":"err","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"view/html.go","lineNumber":98,"sourceCode":"\t\t\t\treturn template.HTML(\"\")\n\t\t\t},\n\t\t},\n\t\tfuncs: make(template.FuncMap),\n\t\tbufPool: &sync.Pool{New: func() any {\n\t\t\treturn new(bytes.Buffer)\n\t\t}},\n\t}\n\n\treturn s\n}\n\n// RootDir sets the directory to be used as a starting point\n// to load templates from the provided file system.\nfunc (s *HTMLEngine) RootDir(root string) *HTMLEngine {\n\tif s.fs != nil && root != \"\" && root != \"/\" && root != \".\" && root != s.rootDir {\n\t\tsub, err := fs.Sub(s.fs, root)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\ts.fs = sub // here so the \"middleware\" can work.\n\t}\n\n\ts.rootDir = filepath.ToSlash(root)\n\treturn s\n}\n\n// FS change templates DIR\nfunc (s *HTMLEngine) FS(dirOrFS any) *HTMLEngine {\n\ts.fs = getFS(dirOrFS)\n\treturn s\n}\n\n// Name returns the engine's name.\nfunc (s *HTMLEngine) Name() string {\n\treturn s.name\n}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/view/html.go#L80-L116","documentation":"HTMLEngine.RootDir applies fs.Sub(s.fs, root) when the engine already holds a filesystem and a non-trivial different root is set. If the requested subdirectory does not exist in that filesystem, fs.Sub errors and the engine panics — an HTML template engine can't function without a valid template root.","triggerScenarios":"Calling html.RootDir(\"templates\") after view.HTMLEngine(view.FS(fsys)) where \"templates\" is not a directory inside fsys, or calling RootDir twice with conflicting values.","commonSituations":"Embedded FS path prefix confusion (embed.FS paths start at the package dir), renaming the templates folder without updating RootDir, or OS path separators (\"\\\\\") instead of slashes.","solutions":["Check that the directory exists inside the FS before calling RootDir (fs.Stat(fsys, name)).","Pass the root directly at construction: view.HTMLEngine(view.FS(fsys), \"templates\").","Use forward slashes and paths relative to the FS root, never OS-specific paths.","Avoid chaining RootDir with different values; set it once."],"exampleFix":"// before\neng := view.HTMLEngine(view.FS(fsys))\neng.RootDir(\"views\\\\pages\") // wrong separator/path -> panic\n// after\neng := view.HTMLEngine(view.FS(fsys), \"views/pages\")","handlingStrategy":"validation","validationCode":"const tplRoot = \"templates\" // forward slashes only\nif _, err := fs.Stat(fsys, tplRoot); err != nil {\n\tlog.Fatalf(\"html template root missing: %v\", err)\n}\nengine.RootDir(tplRoot)","typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tlog.Fatalf(\"HTMLEngine RootDir failed: %v\", r)\n\t}\n}()","preventionTips":["Use forward-slash FS paths, never OS separators.","Set root at construction time instead of chaining RootDir.","Smoke-test LoadTemplate calls in CI."],"tags":["templates","filesystem","panic","embedded-fs"],"backgroundTag":"template-root-not-found","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}