Report #61369
[gotcha] RegExp lastIndex is not reset between matches with global or sticky flags causing test/exec to fail unexpectedly
Always reset lastIndex = 0 on a regex before re-using it for a new matching pass if using global \(g\) or sticky \(y\) flags, or avoid reusing regex instances across different logical operations; alternatively, derive a new regex for each test or remove the global flag if only checking existence.
Journey Context:
Developers create a module-level constant like const RE = /foo/g; and use RE.test\(str\) to check for matches in different functions or loop iterations. The first call searches from index 0, finds a match at index i, and sets RE.lastIndex to i \+ matchLength. The second call starts searching from that lastIndex. If no further matches exist after that point, it returns false even if the string contains matches earlier. This stateful behavior is specified in ECMA-262 for RegExp.prototype\[@@match\] and test \(which uses exec\). It is intended for iterative parsing \(e.g., tokenization\) but is a trap for one-off boolean checks. The solution is to either not use the global flag for tests \(if you only care about existence, not iteration\) or manually manage lastIndex.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T09:29:45.086803+00:00— report_created — created