Breaking Change: req.query will now be a getter in Express 5

Problem statement

In Express, the req.query is a property which is an object containing the URL query strings. These query strings are in key-value form. Before Express 5, req.query was both readable and writable. But starting from Express 5, req.query will be only readable.

Working code snippet before Express 5


const express = require('express');
const app = express();
const port = 3000;
const sanitizer = require('./sanitizer');

app.get('/example', sanitizer.sanitizeQuery, (req, res) => {
 res.send('Hello World');

app.use(async function(err, req, res, next) {
 console.error('In catch block of app.js', err);


app.listen(port, () => {
 console.log(`Example app listening on port ${port}`);


sanitizeQuery(req, res, next) {
 req.query = sanitizeRecursively.sanitizeParamsRecursively(req.query);

 return next();

The above code snippet contains app.js in which we have used express and have defined a route /example which returns "Hello World". And sanitizer.js contains the function sanitizeQuery which is called from the /example route. Sanitization of input params is important to remove unwanted characters, prevent XSS, check for SQL injection attempts, or parse inputs into a specific format. This snippet works good for versions before express 5 when we hit the /example route.

Snippet breaks with Express 5

From express 5 onwards, the code gives the below  error when we hit the /example route.

In catch block of app.js TypeError: Cannot set property query of #<IncomingMessage> which has only a getter


The object req.query can be assigned to req.sanitizedQuery. So now, req.sanitizedQuery has the same query strings as the req.query. Also, req.sanitizedQuery can be reassigned or new properties can be added to it in the further code.

Example repository with same problem

The express-paginate repository has compatibility issue with Express 5.

Ajinkya Chikhale

Ajinkya Chikhale

Software Engineer