Profiles·Public

express

semver>=4.0.0 <6.0.0postconditions18functions11last verified2026-06-23coverage score100%

Postconditions: what we check

  • app.METHOD · async-route-handler-unhandled-rejection
    error
    WhenWhen an async function is used as a route handler (callback to app.get, app.post, etc.) and contains await expressions without try-catch blocks
    ThrowsUnhandledPromiseRejection
    Required 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 unavailablevisibilityvisible
    Sources[1]
  • app.use · async-middleware-unhandled-rejection
    error
    WhenWhen an async function is used as middleware and contains await expressions without try-catch blocks
    ThrowsUnhandledPromiseRejection
    Required 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 unavailablevisibilityvisible
    Sources[1]
  • app.use · error-middleware-signature
    warning
    WhenWhen defining error-handling middleware
    ThrowsN/A
    Required 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 unavailablevisibilityvisible
    Sources[1]
  • router.METHOD · async-router-handler-unhandled-rejection
    error
    WhenWhen an async function is used as a router handler and contains await expressions without try-catch blocks
    ThrowsUnhandledPromiseRejection
    Required 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 unavailablevisibilityvisible
    Sources[1]
  • router.use · async-router-middleware-unhandled-rejection
    error
    WhenWhen an async function is used as router middleware and contains await expressions without try-catch blocks
    ThrowsUnhandledPromiseRejection
    Required handlingMust wrap async operations in try-catch blocks and call next(err). Same requirements as app.use middleware.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • express.json · json-parse-syntax-error
    error
    WhenWhen request body contains malformed JSON that cannot be parsed
    ThrowsSyntaxError (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
    Sources[2][3]
  • express.json · json-payload-too-large
    warning
    WhenWhen request body exceeds the configured limit option (default 100kb)
    ThrowsHttpError (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
    Sources[2][4]
  • express.json · json-charset-unsupported
    warning
    WhenWhen request body uses an unsupported character encoding
    ThrowsHttpError (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 performancevisibilityvisible
    Sources[5]
  • express.urlencoded · urlencoded-parameters-too-many
    warning
    WhenWhen URL-encoded request body contains more parameters than the configured parameterLimit (default 1000)
    ThrowsHttpError (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 performancevisibilityvisible
    Sources[6]
  • express.urlencoded · urlencoded-payload-too-large
    warning
    WhenWhen URL-encoded request body exceeds the configured limit (default 100kb)
    ThrowsHttpError (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 performancevisibilityvisible
    Sources[4]
  • res.sendFile · sendfile-file-not-found
    error
    WhenWhen the file path does not exist or the filename is too long
    ThrowsHttpError (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
    Sources[7][8]
  • res.sendFile · sendfile-forbidden-path
    error
    WhenWhen the file path traverses outside the root directory or accesses a dotfile with dotfiles option set to 'deny'
    ThrowsHttpError (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 breachvisibilitysilent
    Sources[8]
  • res.download · download-file-error
    error
    WhenWhen the file does not exist, is inaccessible, or the transfer fails
    ThrowsError (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 unavailablevisibilityvisible
    Sources[9]
  • app.listen · listen-eaddrinuse
    error
    WhenWhen the specified port is already in use by another process
    ThrowsError (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
    Sources[10][11]
  • app.listen · listen-eacces
    error
    WhenWhen the process lacks permission to bind to the specified port (typically ports below 1024 on Unix systems)
    ThrowsError (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 unavailablevisibilityvisible
    Sources[11]
  • res.render · render-view-not-found
    error
    WhenWhen the specified view template file cannot be found by the configured view engine
    ThrowsError ('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 unavailablevisibilityvisible
    Sources[12]
  • res.render · render-template-error
    error
    WhenWhen the template engine encounters a syntax error or runtime error during template compilation/rendering
    ThrowsError (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 unavailablevisibilityvisible
    Sources[12]
  • express.static · static-fallthrough-disabled
    warning
    WhenWhen express.static is configured with fallthrough: false and a requested file is not found
    ThrowsHttpError (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 performancevisibilityvisible
    Sources[13]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
  • [1]
    expressjs.com/en/guide/error-handling.html
    Error Handling
  • [2]
    expressjs.com/en/api.html
    Api
  • [6]
    expressjs.com/en/api.html
    Api
  • [7]
    expressjs.com/en/api.html
    Api
  • [9]
    expressjs.com/en/api.html
    Api
  • [10]
    expressjs.com/en/api.html
    Api
  • [11]
    nodejs.org/api/net.html
    Net
  • [12]
    expressjs.com/en/api.html
    Api
  • [13]
    expressjs.com/en/api.html
    Api
Source code

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

Error Handling Best Practices

Async/Await 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

Middleware Patterns

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

Notes

Key Behavioral Patterns

  1. 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
  2. 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
  3. Express 5.x Improvements

    • Automatically handles promise rejections
    • Calls next(value) when async handlers reject or throw
    • Reduces boilerplate try-catch code
  4. 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:

  1. Proper async error handling with try-catch + next(err)
  2. Missing error handling in async route handlers
  3. Error-handling middleware patterns
  4. 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

  1. Documentation Review: Official Express.js error handling guide and middleware docs
  2. CVE Analysis: Reviewed Express CVE databases and GitHub security issues
  3. Best Practices Research: Community articles, blog posts, and npm packages
  4. Real-World Usage: Analyzed test repositories (Express not heavily used in available repos)
  5. 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.

Need a different package?
Request a profile