res.render()/app.render() throws opaque TypeError for a view name ending in "."
- 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
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