Error: No default engine was specified and no extension was provided Error: No default engine was specified and no extension was provided express express

Error: No default engine was specified and no extension was provided


The res.render stuff will throw an error if you're not using a view engine.

If you just want to serve json replace the res.render('error', { error: err }); lines in your code with:

res.json({ error: err })

PS: People usually also have message in the returned object:

res.status(err.status || 500);res.json({  message: err.message,  error: err});


You are missing the view engine, for example use jade:

change your

app.set('view engine', 'html');

with

app.set('view engine', 'jade');

If you want use a html friendly syntax use instead ejs

app.engine('html', require('ejs').renderFile);app.set('view engine', 'html');

EDIT

As you can read from view.js Express View Module

module.exports = View;/** * Initialize a new `View` with the given `name`. * * Options: * *   - `defaultEngine` the default template engine name *   - `engines` template engine require() cache *   - `root` root path for view lookup * * @param {String} name * @param {Object} options * @api private */function View(name, options) {  options = options || {};  this.name = name;  this.root = options.root;  var engines = options.engines;  this.defaultEngine = options.defaultEngine;  var ext = this.ext = extname(name);  if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');  if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);  this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);  this.path = this.lookup(name);}

You must have installed a default engine

Express search default layout view by program.template as you can read below:

mkdir(path + '/views', function(){      switch (program.template) {        case 'ejs':          write(path + '/views/index.ejs', ejsIndex);          break;        case 'jade':          write(path + '/views/layout.jade', jadeLayout);          write(path + '/views/index.jade', jadeIndex);          break;        case 'jshtml':          write(path + '/views/layout.jshtml', jshtmlLayout);          write(path + '/views/index.jshtml', jshtmlIndex);          break;        case 'hjs':          write(path + '/views/index.hjs', hoganIndex);          break;      }    });

and as you can read below:

program.template = 'jade';if (program.ejs) program.template = 'ejs';if (program.jshtml) program.template = 'jshtml';if (program.hogan) program.template = 'hjs';

the default view engine is jade


Comment out the res.render lines in your code and add in next(err); instead. If you're not using a view engine, the res.render stuff will throw an error.

Sorry, you'll have to comment out this line as well:

app.set('view engine', 'html');

My solution would result in not using a view engine though. You don't need a view engine, but if that's the goal, try this:

app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'jade');//swap jade for ejs etc

You'll need the res.render lines when using a view engine as well. Something like this:

// error handlers// development error handler// will print stacktraceif (app.get('env') === 'development') {  app.use(function(err, req, res, next) {    res.status(err.status || 500);    res.render('error', {    message: err.message,    error: err    });  });}// production error handler// no stacktraces leaked to userapp.use(function(err, req, res, next) {  res.status(err.status || 500);  next(err);  res.render('error', {  message: err.message,  error: {}  });});