Summary
String.prototype.replace(re, fn) invokes the replacer callback zero times for a regex on the fancy-regex fallback path (backreference + lookahead) — but only inside a large module graph. The same code in isolation works. The result is a silent wrong answer ([] instead of the parsed path), not a crash.
This is what currently stops a standard Express app from booting.
Symptom
$ ./app_bin
SyntaxError: intrinsic %% does not exist!
$ curl localhost:3000/ -> status=000 (never listens)
Localization
get-intrinsic's stringToPath uses rePropName, which carries a backreference (\2) and a lookahead — i.e. per CLAUDE.md, perry-runtime/src/regex.rs falls back from the regex crate to fancy-regex for it.
Probe inserted into node_modules/get-intrinsic/index.js:
[P] in="%String.prototype.indexOf%"
[P] uncurried $replace cb=0 result=[] <- callback never fires
[P] direct .replace cb=0 direct=[] <- not the uncurry-bind either
[P] rePropName.exec ="String" source.len=97 flags=g <- regex object is INTACT
[P] FRESH simple regex=["String","prototype","indexOf"] <- replace+callback works generally
So stringToPath returns [] -> intrinsicBaseName = '' -> '%' + '' + '%' -> %% -> throw (get-intrinsic/index.js:294, via :309-311).
The discriminator is sharp:
exec on that same regex object works
- a fresh simple regex with a callback works
- the identical code in a small graph (35 modules) works
- in the full 139-module Express graph it returns
[]
So the suspect is replace-with-callback on the fancy-regex path, going silently empty at graph scale.
Repro
npm i express@5.2.1
# package.json: { "perry": { "compilePackages": ["*"] } }
perry app.ts -o app_bin && ./app_bin
Compile is clean (139 modules: 139 native, 0 JavaScript, zero codegen failures, no escape-hatch env vars).
Split out of #3527 — every bug in that issue's original inventory is now fixed; this is a new, scale-emergent blocker that replaced them.
Summary
String.prototype.replace(re, fn)invokes the replacer callback zero times for a regex on the fancy-regex fallback path (backreference + lookahead) — but only inside a large module graph. The same code in isolation works. The result is a silent wrong answer ([]instead of the parsed path), not a crash.This is what currently stops a standard Express app from booting.
Symptom
Localization
get-intrinsic'sstringToPathusesrePropName, which carries a backreference (\2) and a lookahead — i.e. perCLAUDE.md,perry-runtime/src/regex.rsfalls back from theregexcrate tofancy-regexfor it.Probe inserted into
node_modules/get-intrinsic/index.js:So
stringToPathreturns[]->intrinsicBaseName = ''->'%' + '' + '%'->%%-> throw (get-intrinsic/index.js:294, via :309-311).The discriminator is sharp:
execon that same regex object works[]So the suspect is
replace-with-callback on the fancy-regex path, going silently empty at graph scale.Repro
Compile is clean (139 modules: 139 native, 0 JavaScript, zero codegen failures, no escape-hatch env vars).
Split out of #3527 — every bug in that issue's original inventory is now fixed; this is a new, scale-emergent blocker that replaced them.