Skip to content

link: perry-ext-* staticlibs bundle a feature-stripped perry-runtime that wins the link — regex/Temporal silently degrade (blocks Express boot) #6303

Description

@proggeramlug

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions