Skip to content

[Bug]: Unicode regex with a one-character class before $ misses letters outside the BMP on Electron 44 (composerContextLegacy test fails) #18272

Open

Description

@EdwinMisael

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

packages/contracts or packages/shared

Steps to reproduce

  1. On main, run vp test run src/composerContextLegacy.test.ts from packages/shared.
  2. The case does not replace terminal labels embedded in 𐐀@build:7 fails.

Minimal engine repro (no project code), saved as probe.js:

const s = "\u{10400}"; // DESERET CAPITAL LETTER LONG I, a letter outside the BMP
console.log(process.versions.v8, {
  classBeforeEnd: /[\p{L}]$/u.test(s),         // false (wrong)
  literalBeforeEnd: /[\u{10400}]$/u.test(s),   // false (wrong)
  alternation: /(?:\p{L})$/u.test(s),          // true
  quantified: /[\p{L}]+$/u.test(s),            // true
  unanchored: /[\p{L}]/u.test(s),              // true
});

Run it with ELECTRON_RUN_AS_NODE=1 <the desktop app's electron binary> probe.js, or with Node 26.5.

Expected behavior

/[\p{L}\p{N}\p{M}_@.-]$/u (packages/shared/src/composerContextLegacy.ts, line 423) matches when the text before the label ends in a letter outside the BMP. The legacy-context upgrade then leaves a terminal label glued to that letter as plain text, as the test expects.

Actual behavior

On the affected engines, a single character class directly before $ with the u flag never matches a character outside the BMP, even when the class names that exact code point. So line 423 returns false and the label is turned into a chip.

It is an engine fault, not a logic error: the same check written as an alternation is correct on the same engines. Checks anchored at the start (^[x]), quantified classes, and unanchored classes read correctly.

Impact

Minor bug or occasional failure

Version or commit

main @ 2625327

Environment

macOS 27.0.1. Fails on Electron 44.4.5 (V8 15.2.124.28-electron.0, the version in pnpm-workspace.yaml) and on Node 26.5.0 (reports V8 14.6.202.34-node.24), which the test runner uses here.

Workaround

Use an alternation instead of a one-character class before $. This passes the failing test and matches the astral letter on both engines above:

/(?:\p{L}|\p{N}|\p{M}|[_@.-])$/u.test(body.slice(0, at))

A search of apps/ and packages/ found no other unanchored one-character class before $ that can meet a character outside the BMP. The engine fault itself probably belongs upstream in V8.

Activity

  1. juliusmarminge commented on Oct 11, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    This is an engine regression, not a logic bug in composerContextLegacy.ts. The regex on line 423 (/[\p{L}\p{N}\p{M}_@.-]$/u) is correct, and so is the 𐐀@build:7 test case. On V8 11.3 (Node 20), /[\p{L}]$/u.test('\u{10400}') returns true as expected. I couldn't test V8 14.6 or 15.2 here. The fault belongs in V8's tracker.

    Since our pinned Electron is affected and a test fails on main, I'm keeping this open as upstream + enhancement for a small defensive change: rewrite that check as the alternation you suggested, /(?:\p{L}|\p{N}|\p{M}|[_@.-])$/u, and add a comment linking the V8 bug. A focused PR that does exactly this is welcome. If you file the V8 issue, please link it here.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequested improvement or new capability.upstreamvia-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions