{"id":"d9fd5aafaca0abe4","repo":"expressjs/express","slug":"no-default-engine-was-specified-and-no-extension-w","errorCode":null,"errorMessage":"No default engine was specified and no extension was provided.","messagePattern":"No default engine was specified and no extension was provided\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/view.js","lineNumber":61,"sourceCode":" *   - `defaultEngine` the default template engine name\n *   - `engines` template engine require() cache\n *   - `root` root path for view lookup\n *\n * @param {string} name\n * @param {object} options\n * @public\n */\n\nfunction View(name, options) {\n  var opts = options || {};\n\n  this.defaultEngine = opts.defaultEngine;\n  this.ext = extname(name);\n  this.name = name;\n  this.root = opts.root;\n\n  if (!this.ext && !this.defaultEngine) {\n    throw new Error('No default engine was specified and no extension was provided.');\n  }\n\n  var fileName = name;\n\n  if (!this.ext) {\n    // get extension from default engine name\n    this.ext = this.defaultEngine[0] !== '.'\n      ? '.' + this.defaultEngine\n      : this.defaultEngine;\n\n    fileName += this.ext;\n  }\n\n  if (!opts.engines[this.ext]) {\n    // load engine\n    var mod = this.ext.slice(1)\n    debug('require \"%s\"', mod)\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/expressjs/express/blob/a3714473feb3d2908add734d340e7755fd85e0a3/lib/view.js#L43-L79","documentation":"The View constructor (lib/view.js:60-62) needs to know which template engine to use. It derives this from the file extension of the view name, falling back to the app's 'view engine' setting. If the render name has no extension and no default engine was configured, Express cannot pick an engine and throws synchronously.","triggerScenarios":"res.render('index') (no extension) without ever calling app.set('view engine', 'ejs'|'pug'|...); calling app.render() on a bare name with the 'view engine' setting unset or misspelled (e.g. app.set('view-engine', 'ejs') — wrong key, a very common typo).","commonSituations":"Tutorial code that installed the engine package but skipped the app.set('view engine', ...) line; the 'view-engine' hyphen typo (silently sets an unused setting); rendering from a mounted sub-app that doesn't inherit the parent's setting the way the developer expected; tests constructing the app without the shared configuration bootstrap.","solutions":["Set a default engine: app.set('view engine', 'pug') — note the space, not a hyphen.","Or include the extension explicitly in every render call: res.render('index.pug').","If using a mounted sub-app, set 'view engine' on the sub-app too (settings like this are consulted on the app doing the rendering)."],"exampleFix":"// before\napp.set('view-engine', 'ejs'); // typo: sets an unrelated key\nres.render('index');\n// after\napp.set('view engine', 'ejs');\nres.render('index');","handlingStrategy":"validation","validationCode":"if (!app.get('view engine') && !path.extname(viewName)) {\n  throw new Error(`Cannot render '${viewName}': set app.set('view engine', ...) or include the file extension`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  res.render('index'); // no extension\n} catch (err) {\n  if (/No default engine was specified/.test(err.message)) {\n    // configure app.set('view engine', 'pug') or render 'index.pug'\n  }\n  next(err);\n}","preventionTips":["Always call app.set('view engine', '<ext>') during app setup, before any route renders.","Alternatively, always include the extension in render calls: res.render('index.ejs').","Centralize view configuration in one bootstrap module so it can't be skipped in some entry points.","Smoke-test one render in CI so missing engine config fails the build, not production."],"tags":["express","view-engine","configuration","rendering"],"analyzedSha":"a3714473feb3d2908add734d340e7755fd85e0a3","analyzedAt":"2026-07-31T18:55:36.968Z","schemaVersion":2}