{"id":"5b7fa15a36eee5d4","repo":"expressjs/express","slug":"status-must-be-a-number","errorCode":null,"errorMessage":"Status must be a number","messagePattern":"Status must be a number","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/response.js","lineNumber":835,"sourceCode":"  var body;\n  var status = 302;\n\n  // allow status / url\n  if (arguments.length === 2) {\n    status = arguments[0]\n    address = arguments[1]\n  }\n\n  if (!address) {\n    deprecate('Provide a url argument');\n  }\n\n  if (typeof address !== 'string') {\n    deprecate('Url must be a string');\n  }\n\n  if (typeof status !== 'number') {\n    deprecate('Status must be a number');\n  }\n\n  // Set location header\n  address = this.location(address).get('Location');\n\n  // Support text/{plain,html} by default\n  this.format({\n    text: function(){\n      body = statuses.message[status] + '. Redirecting to ' + address\n    },\n\n    html: function(){\n      var u = escapeHtml(address);\n      body = '<!DOCTYPE html><head><title>' + statuses.message[status] + '</title></head>'\n       + '<body><p>' + statuses.message[status] + '. Redirecting to ' + u + '</p></body>'\n    },\n\n    default: function(){","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/expressjs/express/blob/a3714473feb3d2908add734d340e7755fd85e0a3/lib/response.js#L817-L853","documentation":"A deprecation warning (via `deprecate()`, not a throw) from `res.redirect`'s two-argument form `res.redirect(status, url)` when the first argument is not a number. Execution continues and the non-numeric status is later used to index `statuses.message[status]` and set the response code, yielding an undefined reason phrase or invalid status; older Express accepted `res.redirect(url, status)` in either order, and this warning flags that removed leniency.","triggerScenarios":"`res.redirect('/login', 301)` (Express 3-era reversed argument order), `res.redirect('301', url)` with the status as a string, or a status pulled from config/env that arrives as a string.","commonSituations":"Legacy code migrated from Express 3 where `res.redirect(url, status)` was allowed; status codes read from environment variables or JSON that are strings; passing `err.status` that was set to a string.","solutions":["Use the correct order with a numeric status: `res.redirect(301, '/login')`.","Coerce string statuses to numbers first: `res.redirect(Number(status), url)`.","If you just want a default redirect, drop the status entirely — `res.redirect(url)` uses 302."],"exampleFix":"// before\nres.redirect('/login', 301);\n// after\nres.redirect(301, '/login');","handlingStrategy":"type-guard","validationCode":"const status = Number(rawStatus);\nif (!Number.isInteger(status) || status < 300 || status > 399) {\n  return res.redirect(302, target); // sane default redirect status\n}\nres.redirect(status, target);","typeGuard":"function isRedirectStatus(s) {\n  return Number.isInteger(s) && s >= 300 && s <= 399;\n}","tryCatchPattern":null,"preventionTips":["res.redirect(status, url) requires a numeric status — config files and query strings give you strings, so coerce with Number() first","Prefer the one-argument res.redirect(url) form (defaults to 302) unless you specifically need 301/303/307/308","Restrict accepted values to the 3xx redirect codes you actually intend to use"],"tags":["express","redirect","deprecation","status-code"],"analyzedSha":"a3714473feb3d2908add734d340e7755fd85e0a3","analyzedAt":"2026-07-31T18:55:36.968Z","schemaVersion":2}