Skip to content
Latchkey

Node.js "--unhandled-rejections=strict" Changed CI Exit Behavior

Node’s --unhandled-rejections flag controls what happens when a promise rejects unhandled. A pipeline that set warn (or ran old Node) tolerated rejections; switching to strict/throw makes them fatal.

What this error means

After a Node upgrade or a changed NODE_OPTIONS, a job that previously only logged a warning now exits non-zero on the same unhandled rejection. Nothing in your code changed - only the rejection mode did.

Node output
# old behaviour (warn): job stayed green
(node:1) UnhandledPromiseRejectionWarning: TypeError: ...

# new behaviour (strict/throw): job fails
node:internal/process/promises:288  ... code: 'ERR_UNHANDLED_REJECTION'

Common causes

The default mode changed across Node versions

Older Node warned on unhandled rejections; Node 15+ defaults to throw. A runner image bump to a newer Node flips the same code from warning to fatal.

NODE_OPTIONS sets a stricter mode

A pipeline that adds --unhandled-rejections=strict raises severity so even rejections inside the first tick of loading abort the process.

How to fix it

Fix the rejection rather than the mode

The correct response to a newly-fatal rejection is to handle it. Lowering the mode just hides a real bug.

  1. Find the unhandled rejection in the stack or the prior warning.
  2. Await it in try/catch or attach .catch().
  3. Keep throw/strict so future rejections stay visible.

Set the mode deliberately if you must

If you genuinely need to soften behaviour during a migration, set the mode explicitly so it is documented - but treat it as temporary.

Terminal / workflow
# strict (recommended long-term)
node --unhandled-rejections=strict app.mjs
# or via env
NODE_OPTIONS=--unhandled-rejections=strict

How to prevent it

  • Pin a Node version in CI so the default rejection mode does not change under you.
  • Lint for floating promises so rejections never go unhandled in the first place.
  • Keep --unhandled-rejections=strict and treat any rejection as a bug.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →