Skip to content

fix: warn instead of throw for removed bugfixes option in preset-env#18143

Open
mvanhorn wants to merge 1 commit into
babel:mainfrom
mvanhorn:fix/preset-env-bugfixes-warn
Open

fix: warn instead of throw for removed bugfixes option in preset-env#18143
mvanhorn wants to merge 1 commit into
babel:mainfrom
mvanhorn:fix/preset-env-bugfixes-warn

Conversation

@mvanhorn

Copy link
Copy Markdown

Summary

@babel/preset-env currently throws a hard error when the removed bugfixes option is passed. This turns a harmless leftover config key into a build-breaking crash. This PR downgrades it to a console.warn, as suggested in the issue thread.

Background

bugfixes was removed in Babel 8 because bugfix plugins are now always enabled, so the option is a no-op. But configs carried over from Babel 7 (or shared presets that still set it) commonly include bugfixes: true. On Babel 8 those configs fail outright at normalizeOptions:

v.invariant(
  !Object.hasOwn(opts, "bugfixes"),
  "The 'bugfixes' option has been removed, ...",
);

Since the option no longer does anything, a hard error is stricter than necessary. In the issue, a core maintainer noted that downgrading it to a console.warn is reasonable, matching how the corejs-without-useBuiltIns case is already handled in this same file.

Fix

When bugfixes is present, emit a console.warn (same message, same newline-wrapped WARNING (@babel/preset-env): style as the existing corejs warning) instead of throwing.

There is one subtlety: bugfixes is not in TopLevelOptions, and the very next line calls v.validateTopLevelOptions, which throws on any unknown top-level key. So simply swapping the invariant for a warning would still crash. To avoid that, the option is stripped from a shallow copy of the input before validation runs. The caller's original options object is left untouched (only the local reference is reassigned), and configs that never pass bugfixes are completely unaffected.

Testing

Added a focused case to packages/babel-preset-env/test/normalize-options.skip-bundled.js that spies on console.warn and asserts: passing bugfixes: true/false no longer throws, a warning mentioning bugfixes is emitted, the caller's options object is not mutated, and no warning fires when the option is absent. The babel-preset-env normalize-options suite passes (30 tests) and make tscheck is clean across the monorepo.

Closes #18096

AI was used for assistance.

`@babel/preset-env` threw a hard error when the removed `bugfixes` option
was passed, which breaks configs carried over from Babel 7 even though the
option is now a harmless no-op (bugfix plugins are always enabled). Downgrade
it to a `console.warn`, matching the existing `corejs` warning style in the
same file.

Because `bugfixes` is not a valid top-level option, `validateTopLevelOptions`
would still throw on the next line, so the option is stripped from a shallow
copy of the input (leaving the caller's object untouched) before validation
runs. Configs that do not pass `bugfixes` are unaffected.

Closes babel#18096
@github-actions

Copy link
Copy Markdown

❌ Automation signals

Activity patterns show signs of automation.

View full analysis →

This is an automated analysis by AgentScan

@babel-bot

Copy link
Copy Markdown
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/61942

@pkg-pr-new

pkg-pr-new Bot commented Jul 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

commit: e8a630f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

babel/preset-env - erroring out when bugfixes is true puts third-party software in an unresolvable situation

2 participants