{"id":16029,"library":"finalhandler","title":"finalhandler: HTTP Final Responder","description":"finalhandler is a Node.js utility function designed to standardize the final steps of an HTTP request within a server or middleware chain. It gracefully handles both successful completion (responding with a 404 for unhandled requests) and error scenarios, ensuring that the `ServerResponse` object is properly concluded and the `IncomingMessage` stream is unpiped. Currently at version 2.1.1, the library maintains an active development and maintenance cadence, with recent updates in both its v1 and v2 major versions. Its primary differentiation lies in providing a low-level, unopinionated mechanism for robust error and 404 response handling, including options for custom error logging, making it a foundational component for web frameworks like Express and Connect.","status":"active","version":"2.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/pillarjs/finalhandler","tags":["javascript"],"install":[{"cmd":"npm install finalhandler","lang":"bash","label":"npm"},{"cmd":"yarn add finalhandler","lang":"bash","label":"yarn"},{"cmd":"pnpm add finalhandler","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"finalhandler is primarily a CommonJS module. This is the canonical way to import it in Node.js CJS environments.","symbol":"finalhandler","correct":"const finalhandler = require('finalhandler')"},{"note":"When using finalhandler in an ES Module context, it must be imported as a default export since it's a CommonJS module. Named imports will not work directly.","wrong":"import { finalhandler } from 'finalhandler'","symbol":"finalhandler","correct":"import finalhandler from 'finalhandler'"},{"note":"For advanced scenarios in ES Modules where CJS `require` semantics are strictly needed, `createRequire` can be used to load CommonJS modules.","symbol":"finalhandler","correct":"import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); const finalhandler = require('finalhandler');"}],"quickstart":{"code":"const finalhandler = require('finalhandler');\nconst fs = require('fs');\nconst http = require('http');\n\nconst server = http.createServer((req, res) => {\n  const done = finalhandler(req, res, { onerror: logerror });\n\n  fs.readFile('index.html', (err, buf) => {\n    if (err) return done(err);\n    res.setHeader('Content-Type', 'text/html');\n    res.end(buf);\n  });\n});\n\nserver.listen(3000, () => {\n  console.log('Server listening on port 3000');\n});\n\nfunction logerror (err) {\n  console.error('Error encountered:', err.stack || err.toString());\n}\n\n// To make this runnable, create a dummy index.html\n// For example, echo '<h1>Hello World!</h1>' > index.html","lang":"javascript","description":"Demonstrates how to use `finalhandler` to set up a basic HTTP server that serves a file, logging any errors to the console using the `onerror` option, and responding with appropriate HTTP status codes."},"warnings":[{"fix":"Upgrade Node.js to version 18.0.0 or higher, or explicitly lock `finalhandler` to a 1.x version in your `package.json`.","message":"Version 2.0.0 of `finalhandler` dropped support for Node.js versions older than 18.0.0. Projects running on Node.js <18 will need to upgrade their Node.js environment or remain on `finalhandler` v1.x.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Review existing HTTP response headers in your application if upgrading from versions prior to 1.2.0 to ensure desired headers are explicitly set where necessary, particularly for error responses.","message":"Version 1.2.0 introduced a change by removing 'set content headers that break response'. This was an internal adjustment to avoid issues but could subtly affect applications that relied on specific default headers being set by `finalhandler` in earlier versions.","severity":"breaking","affected_versions":">=1.2.0"},{"fix":"During development, ensure `NODE_ENV=development` to see stack traces. In production, utilize the `onerror` option to log detailed error information to a secure logging system, rather than exposing it to clients.","message":"By default, when `NODE_ENV` is set to 'production' (or `options.env` is 'production'), `finalhandler` will suppress the stack trace in the HTTP error response body for security reasons. Instead, it will send a generic status message.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure `finalhandler` is called as early as possible in the error handling chain, or use a conditional check like `if (!res.headersSent) { res.statusCode = ... }` before modifying headers if `finalhandler` is only one part of a more complex error handling strategy.","message":"If `finalhandler` is invoked after `res.headersSent` is `true` (meaning headers have already been sent to the client), it will not attempt to set new headers or status codes. While it will still try to end the response, any attempts to modify the status code or add headers for the error will be ignored, potentially leading to incorrect client-side error handling if the initial headers were misleading.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"In ES Modules, use `import finalhandler from 'finalhandler'` for loading. If you require `require()` functionality within an ESM file for other CJS modules, you can use `import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);`.","cause":"Attempting to use CommonJS `require()` syntax directly in a Node.js ES Module file without a compatibility shim.","error":"ReferenceError: require is not defined"},{"fix":"Review your middleware chain and error handling logic. Ensure that `finalhandler` is called exclusively when no other response has been sent, or that preceding middleware correctly passes errors down the chain without prematurely sending a response. Check `res.headersSent` before attempting to modify headers.","cause":"This error occurs when an attempt is made to modify HTTP headers or the status code after the server has already sent the response headers or the full response body to the client. This typically happens if multiple error handlers or middleware incorrectly try to respond to the same request.","error":"Error: Can't set headers after they are sent to the client"},{"fix":"This is expected behavior in production. For debugging, ensure `NODE_ENV=development` or `options.env` is not 'production'. For production error visibility, implement custom error logging using the `onerror` option to send stack traces to an internal logging service instead of exposing them to clients.","cause":"`NODE_ENV` environment variable is set to 'production', or the `env` option passed to `finalhandler` is explicitly 'production'. In production environments, `finalhandler` intentionally omits stack traces from HTTP responses for security.","error":"Error response does not contain a stack trace in production"}],"ecosystem":"npm"}