{"record":{"id":"2b488a6cba753058","repo":"kataras/iris","slug":"s-extension-is-not-a-valid-jet-engine-extension","errorCode":null,"errorMessage":"%s extension is not a valid jet engine extension[%s]","messagePattern":"(.+?) extension is not a valid jet engine extension\\[(.+?)\\]","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"view/jet.go","lineNumber":73,"sourceCode":"\n// Jet creates and returns a new jet view engine.\n// The given \"extension\" MUST begin with a dot.\n//\n// Usage:\n// Jet(\"./views\", \".jet\") or\n// Jet(iris.Dir(\"./views\"), \".jet\") or\n// Jet(embed.FS, \".jet\") or Jet(AssetFile(), \".jet\") for embedded data.\nfunc Jet(dirOrFS any, extension string) *JetEngine {\n\textOK := false\n\tfor _, ext := range jetExtensions {\n\t\tif ext == extension {\n\t\t\textOK = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !extOK {\n\t\tpanic(fmt.Sprintf(\"%s extension is not a valid jet engine extension[%s]\", extension, strings.Join(jetExtensions[0:], \", \")))\n\t}\n\n\ts := &JetEngine{\n\t\tfs:                getFS(dirOrFS),\n\t\trootDir:           \"/\",\n\t\textension:         extension,\n\t\tloader:            &jetLoader{fs: getFS(dirOrFS)},\n\t\tjetDataContextKey: \"_jet\",\n\t}\n\n\treturn s\n}\n\n// String returns the name of this view engine, the \"jet\".\nfunc (s *JetEngine) String() string {\n\treturn jetEngineName\n}\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/view/jet.go#L55-L91","documentation":"The jet view engine only supports the fixed extension set .html.jet, .jet.html, and .jet because the vendored jet loader registers handlers per extension and cannot be reconfigured. Passing any other extension to view.Jet makes the engine refuse to start with this formatted panic listing the valid options.","triggerScenarios":"view.Jet(\"./views\", \".gohtml\"), \".html\", \".tmpl\" or any extension not in the jetExtensions list — the extOK loop finds no match and panics.","commonSituations":"Copy-pasting engine setup from the HTML engine docs (which use .html), migrating a project from html/django to jet without renaming template files, or inventing extensions like .jet.tmpl.","solutions":["Use one of the supported extensions: view.Jet(\"./views\", \".jet\") (or .html.jet / .jet.html).","Rename your template files to carry a supported extension (e.g. index.gohtml -> index.jet).","If you need other extensions, use a different engine (HTML/Django) or a custom loader outside view.Jet."],"exampleFix":"// before\neng := view.Jet(\"./views\", \".gohtml\") // panic: not a valid jet extension\n// after\neng := view.Jet(\"./views\", \".jet\")","handlingStrategy":"validation","validationCode":"valid := map[string]bool{\".jet\": true, \".html.jet\": true, \".jet.html\": true}\nif !valid[ext] {\n\tlog.Fatalf(\"extension %q unsupported by jet engine\", ext)\n}","typeGuard":"func isJetExtension(ext string) bool {\n\tswitch ext {\n\tcase \".jet\", \".html.jet\", \".jet.html\":\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"defer func() {\n\tif r := recover(); strings.Contains(fmt.Sprint(r), \"valid jet engine extension\") {\n\t\tlog.Fatalf(\"bad jet extension: %v\", r)\n\t}\n}()","preventionTips":["Always use one of .jet, .html.jet, .jet.html when calling view.Jet.","Rename template files when migrating from other engines.","Keep the extension in a shared constant next to engine setup."],"tags":["templates","jet","panic","validation","wrong-argument"],"backgroundTag":"unsupported-template-extension","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}