#7455·formatjs

icu-messageformat-parser: unguarded \p{White_Space}/\p{Pattern_Syntax} RegExp crashes at module load on engines without those property names (regression vs. the old REGEX_SUPPORTS_U_AND_Y detection)

Author: fang-linCreated Sep 18, 2026Updated Sep 18, 2026

What happens

@formatjs/[email protected] throws at module evaluation time on JS engines that support the u / y regex flags but do not recognise the White_Space / Pattern_Syntax Unicode property names.

Observed on a real Android device running a WeChat Mini Program (WeChat's Android JS runtime is V8):

MiniProgramError
Invalid regular expression: /([^\p{White_Space}\p{Pattern_Syntax}]*)/uy: Invalid property name in character class
SyntaxError: Invalid regular expression: ...
    at new RegExp (<anonymous>)
    at 7801 (https://usr/appservice.app.js:6113:38216)
    ...

Because it happens while the module graph is still being evaluated, it is not catchable by the application:

[wxapplib] Error during require queue flushing
TypeError: Cannot read properties of null (reading 'mount')
TypeError: Cannot read properties of null (reading 'unmount')

The result is a completely blank app. React never mounts, so error boundaries never run and nothing is logged by the app itself. iOS (JavaScriptCore) and the desktop simulator (Chromium) are unaffected — the bug is invisible outside that one engine family.

Where

@formatjs/[email protected], ESM build, index.js:1409:

javascript
const IDENTIFIER_PREFIX_RE = new RegExp("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu");

Top level, unconditional, const.

Why this looks like a regression

Older bundled copies of this parser guarded exactly this case. For example the parser vendored inside [email protected] still contains:

javascript
// IE11 does not support y and u.
var REGEX_SUPPORTS_U_AND_Y = true;
try {
    var re = RE('([^\\p{White_Space}\\p{Pattern_Syntax}]*)', 'yu');
    /**
     * legacy Edge or Xbox One browser
     * Unicode flag support: supported
     * Pattern_Syntax support: not supported
     * See https://github.com/formatjs/formatjs/issues/2822
     */
    REGEX_SUPPORTS_U_AND_Y = re.exec('a')?.[0] === 'a';
} catch (_) {
    REGEX_SUPPORTS_U_AND_Y = false;
}

…together with a hand-written fallback that the comments describe as the code point equivalent of \p{White_Space} and \p{Pattern_Syntax}, selected by if (REGEX_SUPPORTS_U_AND_Y) { … } else { … }.

In 3.5.17 the detection variable does not appear at all (grep -c REGEX_SUPPORTS_U_AND_Y → 0), and the regex is constructed unconditionally. So engines in precisely the category that the old comment called out — "Unicode flag support: supported / Pattern_Syntax support: not supported", the case tracked in #2822 — went from degrading to the fallback to crashing on import.

Impact

For bundled targets this is unrecoverable from the application side: the throw happens during module evaluation, before any application code runs, so it cannot be caught, feature-detected around, or reported by the app. Consumers only see a blank screen on the affected engine.

It is also invisible to static checks. The regex is built from a string via new RegExp, so transpilation targets, browserslist, and AST-level linting all pass — the bundle is valid ES5 and still crashes at runtime.

Suggested fix

Restore the runtime detection and the code-point fallback that earlier versions shipped, or construct IDENTIFIER_PREFIX_RE lazily inside a try/catch so that a failure can fall back rather than take down module evaluation.

Environment

  • @formatjs/icu-messageformat-parser 3.5.17 (reached via intl-messageformat[email protected])
  • WeChat Mini Program, Android client (V8); confirmed working on iOS (JavaScriptCore) and in the desktop simulator with the identical bundle
  • Bundled with webpack via Taro 4.2.1; the ESM entry is the one selected