expressjs / expressjs/express

res.render()/app.render() throws opaque TypeError for a view name ending in "."

Open
#7,350 8 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
69.5k
Forks
25k
Avg merge
4d 20h
Merged PRs (30d)
9

Description

A view name ending in "." causes Express to call require("") in the View constructor, throwing an opaque error instead of resolving the view or reporting a clean lookup error.

Reproduction:

const express = require('express')
const app = express()
app.set('view engine', 'ejs')

// callback is never invoked — throws synchronously:
app.render('index.', (err, html) => {})
// TypeError [ERR_INVALID_ARG_VALUE]: The argument 'id' must be a non-empty string. Received ''

Via res.render('index.') inside a route the same error surfaces as an opaque 500 in the error handler, instead of the usual `Failed to lookup view "index."` error.

Root cause: path.extname('index.') returns '.', which is truthy, so the "no extension -> use default engine" fallback in lib/view.js is skipped. this.ext stays '.', and this.ext.slice(1) becomes '', so require('') is called.

Expected: a view name ending in "." should be handled like any unresolved view — the callback should receive a normal "Failed to lookup view" error, not an opaque require("") TypeError, and app.render() must never throw past its callback.

I have a fix + regression test ready and will open a PR.

Contributor guide

Open the contributing guide

Research direction

Start with lib/view.js and the app.render()/res.render() paths, then reproduce the trailing-dot view name described in the issue. Done means the callback receives the usual Failed to lookup view error, app.render() does not throw past its callback, and the regression test covers the case.

Written by the indexing model from the issue text.

Assessment

Tech stack
express, javascript, node.js
Domain
backend, web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.