express
>=4.0.0 <6.0.0postconditions18functions11last verified2026-06-23coverage score100%Postconditions: what we check
- app.METHOD · async-route-handler-unhandled-rejectionerrorWhenWhen an async function is used as a route handler (callback to app.get, app.post, etc.) and contains await expressions without try-catch blocksThrows
UnhandledPromiseRejectionRequired handlingMust wrap async operations in try-catch blocks and call next(err) with the caught error to forward it to error-handling middleware. Alternatively, use the express-async-errors package or upgrade to Express 5.x for automatic promise rejection handling. Example: app.get('/path', async (req, res, next) => { try { const data = await asyncOperation(); res.json(data); } catch (err) { next(err); // Forward to error handler } });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - app.use · async-middleware-unhandled-rejectionerrorWhenWhen an async function is used as middleware and contains await expressions without try-catch blocksThrows
UnhandledPromiseRejectionRequired handlingMust wrap async operations in try-catch blocks and call next(err) to forward errors to error-handling middleware. Alternatively, use express-async-errors. Example: app.use(async (req, res, next) => { try { await authenticateUser(req); next(); // Continue to next middleware } catch (err) { next(err); // Forward to error handler } });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - app.use · error-middleware-signaturewarningWhenWhen defining error-handling middlewareThrows
N/ARequired handlingError-handling middleware must be defined with exactly 4 parameters (err, req, res, next) to be recognized by Express. Error-handling middleware must be defined AFTER all other middleware and routes. Example: app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - router.METHOD · async-router-handler-unhandled-rejectionerrorWhenWhen an async function is used as a router handler and contains await expressions without try-catch blocksThrows
UnhandledPromiseRejectionRequired handlingMust wrap async operations in try-catch blocks and call next(err). Same requirements as app.METHOD route handlers. Example: const router = express.Router(); router.get('/users', async (req, res, next) => { try { const users = await User.findAll(); res.json(users); } catch (err) { next(err); } });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - router.use · async-router-middleware-unhandled-rejectionerrorWhenWhen an async function is used as router middleware and contains await expressions without try-catch blocksThrows
UnhandledPromiseRejectionRequired handlingMust wrap async operations in try-catch blocks and call next(err). Same requirements as app.use middleware.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - express.json · json-parse-syntax-errorerrorWhenWhen request body contains malformed JSON that cannot be parsedThrows
SyntaxError (status 400, type 'entity.parse.failed')Required handlingMust define error-handling middleware that catches SyntaxError with status 400 and returns an appropriate error response. Without this, the default Express error handler exposes the stack trace in development and returns a generic 500 in production. Example: app.use(express.json()); app.use((err, req, res, next) => { if (err.status === 400 && err.type === 'entity.parse.failed') { return res.status(400).json({ error: 'Invalid JSON' }); } next(err); });costlowin prodsilent failureusers seedegraded performancevisibilitysilent - express.json · json-payload-too-largewarningWhenWhen request body exceeds the configured limit option (default 100kb)Throws
HttpError (status 413, type 'entity.too.large')Required handlingMust handle 413 errors in error-handling middleware. Without this, legitimate large payloads (file uploads via JSON, bulk operations) fail silently with unhelpful error messages. Example: app.use(express.json({ limit: '1mb' })); app.use((err, req, res, next) => { if (err.status === 413) { return res.status(413).json({ error: 'Payload too large' }); } next(err); });costlowin prodsilent failureusers seedegraded performancevisibilityvisible - express.json · json-charset-unsupportedwarningWhenWhen request body uses an unsupported character encodingThrows
HttpError (status 415, type 'charset.unsupported')Required handlingMust handle 415 errors in error-handling middleware to return a clear error message about unsupported encoding.costlowin prodsilent failureusers seedegraded performancevisibilityvisibleSources[5] - express.urlencoded · urlencoded-parameters-too-manywarningWhenWhen URL-encoded request body contains more parameters than the configured parameterLimit (default 1000)Throws
HttpError (status 413, type 'parameters.too.many')Required handlingMust handle this in error-handling middleware. This error is common when forms have dynamically generated fields or when malicious actors attempt hash collision DoS attacks via parameter flooding. Example: app.use(express.urlencoded({ extended: true, parameterLimit: 2000 }));costlowin prodsilent failureusers seedegraded performancevisibilityvisibleSources[6] - express.urlencoded · urlencoded-payload-too-largewarningWhenWhen URL-encoded request body exceeds the configured limit (default 100kb)Throws
HttpError (status 413, type 'entity.too.large')Required handlingSame handling as json-payload-too-large. Must handle 413 errors in error-handling middleware.costlowin prodsilent failureusers seedegraded performancevisibilityvisibleSources[4] - res.sendFile · sendfile-file-not-founderrorWhenWhen the file path does not exist or the filename is too longThrows
HttpError (status 404, original error.code ENOENT or ENAMETOOLONG)Required handlingMust provide an error callback to res.sendFile() or handle the error in error-handling middleware. Without this, missing files cause unhandled errors that crash the request. Must also check res.headersSent before attempting to send an error response, as partial data may have already been transmitted. Example: res.sendFile('/uploads/' + filename, (err) => { if (err) { if (!res.headersSent) { res.status(404).send('File not found'); } } });costlowin prodsilent failureusers seeservice unavailablevisibilityvisible - res.sendFile · sendfile-forbidden-patherrorWhenWhen the file path traverses outside the root directory or accesses a dotfile with dotfiles option set to 'deny'Throws
HttpError (status 403)Required handlingMust handle 403 errors from sendFile. Path traversal attempts (e.g., ../../etc/passwd) are common attack vectors. Always use the root option to restrict file access. Example: res.sendFile(filename, { root: path.join(__dirname, 'uploads') });costhighin prodsilent failureusers seesecurity breachvisibilitysilentSources[8] - res.download · download-file-errorerrorWhenWhen the file does not exist, is inaccessible, or the transfer failsThrows
Error (ENOENT, EACCES, or other fs error)Required handlingMust provide an error callback and check res.headersSent before attempting to send an error response. The response may be partially sent when the error occurs. Example: res.download('/report.pdf', 'report.pdf', (err) => { if (err && !res.headersSent) { res.status(404).send('File not found'); } });costlowin prodsilent failureusers seeservice unavailablevisibilityvisibleSources[9] - app.listen · listen-eaddrinuseerrorWhenWhen the specified port is already in use by another processThrows
Error (code 'EADDRINUSE')Required handlingMust listen for the 'error' event on the returned http.Server object, or handle the error in the listen callback. EADDRINUSE is the most common Express startup failure and causes the process to crash if unhandled. Example: const server = app.listen(3000, (err) => { if (err) { console.error('Failed to start server:', err); process.exit(1); } }); server.on('error', (err) => { if (err.code === 'EADDRINUSE') { console.error('Port 3000 already in use'); process.exit(1); } });costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - app.listen · listen-eacceserrorWhenWhen the process lacks permission to bind to the specified port (typically ports below 1024 on Unix systems)Throws
Error (code 'EACCES')Required handlingMust handle EACCES errors on server startup. Common in production when trying to bind to port 80 or 443 without root privileges.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[11] - res.render · render-view-not-founderrorWhenWhen the specified view template file cannot be found by the configured view engineThrows
Error ('Failed to lookup view "<name>" in views directory')Required handlingMust provide a callback to res.render() or handle errors in error-handling middleware. Missing template files cause 500 errors that expose internal paths if not handled. Example: res.render('dashboard', { user }, (err, html) => { if (err) { return res.status(500).send('Template error'); } res.send(html); });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[12] - res.render · render-template-errorerrorWhenWhen the template engine encounters a syntax error or runtime error during template compilation/renderingThrows
Error (engine-specific error from EJS, Pug, Handlebars, etc.)Required handlingMust handle template rendering errors. Template syntax errors in user-editable templates (email templates, CMS content) cause 500 errors that can take down entire pages.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[12] - express.static · static-fallthrough-disabledwarningWhenWhen express.static is configured with fallthrough: false and a requested file is not foundThrows
HttpError (status 404)Required handlingWhen fallthrough is set to false, file-not-found errors are passed to error-handling middleware via next(err). Must have error-handling middleware to return a proper 404 response. Example: app.use(express.static('public', { fallthrough: false })); app.use((err, req, res, next) => { if (err.status === 404) { return res.status(404).send('Not found'); } next(err); });costlowin prodsilent failureusers seedegraded performancevisibilityvisibleSources[13]
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]expressjs.com/en/guide/error-handling.htmlError Handling
- [2]expressjs.com/en/api.htmlApi
- [6]expressjs.com/en/api.htmlApi
- [7]expressjs.com/en/api.htmlApi
- [9]expressjs.com/en/api.htmlApi
- [10]expressjs.com/en/api.htmlApi
- [11]nodejs.org/api/net.htmlNet
- [12]expressjs.com/en/api.htmlApi
- [13]expressjs.com/en/api.htmlApi
- [3]github.com/expressjs/body-parser/blobexpressjs/body-parser · json.js
- [4]github.com/stream-utils/raw-body/blobstream-utils/raw-body · index.js
- [5]github.com/expressjs/body-parser/blobexpressjs/body-parser · read.js
- [8]github.com/pillarjs/send/blobpillarjs/send · index.js
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources for Express Contract
Package: express Contract Version: 1.0.0 Last Updated: 2026-02-24
Official Documentation
- Express Error Handling Guide - Official guide on error-handling middleware and async errors
- Express Security Updates - Official CVE and security vulnerability tracking
Error Handling Best Practices
- Express Error Handling Patterns | Better Stack Community - Comprehensive patterns for Express error handling
- Global Error Handling in Express.js: Best Practices - DEV Community - Global error handler setup patterns
- How to Implement Error Handling in Express - Modern error handling implementation guide
- Express.js Error Handling 101 - Fundamentals of Express error handling
Async/Await Error Handling
- Using async/await in Express | Zell Liew - Async/await patterns in Express
- Handling Errors with Async/Await in Express | Medium - Try-catch patterns for async routes
- Async Await Error Handling in JavaScript | Code Barbarian - Deep dive into async error handling
- Say Goodbye to Try-Catch: Smart Async Error Handling in Express - DEV Community - Alternative patterns using wrapper functions
- express-async-errors - npm - Package for automatic async error handling
- GitHub Issue #6917 - Add async/await error handling best practices guide - Community discussion on async error handling
CVE Analysis
Active CVEs
-
CVE-2024-10491 - Link Header Injection in response.links() function
- Issue: Arbitrary resource injection via unsanitized data in Link headers
- Impact: Malicious resource preloading using characters like
,,;,<,> - Severity: Medium
-
CVE-2024-29041 - Open Redirect via Malformed URLs
- Affected Versions: < 4.19.0, pre-release 5.0 alpha/beta
- Methods Impacted: res.location(), res.redirect()
- Fixed In: 4.19.2, 5.0.0-beta.3
- Severity: Medium
Historical CVEs
- CVE-2015-1164 - Open redirect vulnerability in express.static
- Directory Traversal - Vulnerabilities in express.static middleware
- DoS Attacks - Sparse arrays and nested query strings causing memory exhaustion
CVE Databases
- Express CVE Details - Comprehensive CVE tracking
- Snyk Express Vulnerabilities - Security vulnerability database
Middleware Patterns
- How to Use Middleware Effectively in Express - Middleware best practices
- Understanding Normal Middleware and Error Handling Middleware in Express.js | Medium - Middleware signatures and patterns
- How to write Custom Error Handler Middleware in Express.js | DEV Community - Custom error handler implementation
Real-World Usage
Test Repositories Analyzed:
- jake-tennis-ai-collections: Express not used (Next.js frontend)
- medusa: Custom framework, not using Express directly
- strapi: Custom framework with different error handling
- n8n, payload, trigger.dev: Checked but Express not in primary dependencies
Note: While Express wasn't found in the analyzed repos, it's one of the most widely used Node.js frameworks (27M+ weekly npm downloads). The contract focuses on well-documented error handling patterns from official docs and community best practices.
Community References
- Stack Overflow: Express Error Handling - Common error handling questions
- GitHub: express-async-errors - Popular solution for async error handling
Notes
Key Behavioral Patterns
-
Error-Handling Middleware Signature
- Must have exactly 4 parameters:
(err, req, res, next) - Must be defined AFTER all routes and regular middleware
- Express uses parameter count to distinguish error handlers from regular middleware
- Must have exactly 4 parameters:
-
Async Route Handler Requirements (Express 4.x)
- Must wrap await expressions in try-catch blocks
- Must call next(err) with caught errors
- Unhandled promise rejections will NOT be caught automatically
-
Express 5.x Improvements
- Automatically handles promise rejections
- Calls next(value) when async handlers reject or throw
- Reduces boilerplate try-catch code
-
Common Anti-Patterns
- Forgetting try-catch in async route handlers → UnhandledPromiseRejection
- Not calling next(err) → errors not reaching error middleware
- Error middleware with wrong parameter count → not recognized as error handler
- Placing error middleware before routes → errors not caught
Real-World Impact
The most critical issue is unhandled promise rejections in async route handlers. This can:
- Crash the Node.js process (in older Node versions)
- Leave the server in an inconsistent state
- Result in hung HTTP requests with no response
- Cause memory leaks from unresolved promises
Testing Strategy
Since Express follows a callback-based API pattern (passing functions to app.get(), app.use(), etc.), the fixtures demonstrate:
- Proper async error handling with try-catch + next(err)
- Missing error handling in async route handlers
- Error-handling middleware patterns
- Common anti-patterns that lead to unhandled rejections
The analyzer may require enhancements to fully detect callback function patterns, but the contract documents the expected behaviors for future tooling improvements.
Research Process
- Documentation Review: Official Express.js error handling guide and middleware docs
- CVE Analysis: Reviewed Express CVE databases and GitHub security issues
- Best Practices Research: Community articles, blog posts, and npm packages
- Real-World Usage: Analyzed test repositories (Express not heavily used in available repos)
- Pattern Analysis: Identified async error handling as the most critical Nark profile
Confidence Level
High Confidence - Express error handling patterns are well-documented with:
- Official documentation clearly stating requirements
- Large community consensus on best practices
- Known issues (CVEs) documented
- Multiple educational resources confirming patterns
- Package ecosystem (express-async-errors) addressing the problem
The contract accurately reflects Express 4.x/5.x behavior for async error handling.