You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
globals: legacy escape()/unescape() throw ReferenceError; bare Node global unresolved #4511
The legacy global functions escape() / unescape() (ECMAScript Annex B,
still standard and present in Node) are not defined — calling them throws ReferenceError at runtime.
Minimal repro
console.log(escape("a b+c"),unescape("a%20b"));
$ perry run t_escape.ts
ReferenceError: identifier is not defined
at <anonymous>
Expected
a%20b%2Bc a b
Notes
Used in the wild by qs (qs/lib/utils.js) for %uXXXX decoding, so any
app pulling in qs (e.g. via stripe) hits this.
Closely related: the Node global object is likewise unresolved — (global as any).x emits Warning: unknown identifier 'global' — assuming global ....
Both are missing global bindings. (globalThis works.)
Environment
perry 0.5.1122 · macOS arm64 · native host target.
Planned PR cut: add the missing Node-compatible global bindings for bare escape / unescape and global, then cover them with focused globals parity fixtures. Non-goals: broader URL/querystring behavior changes, global object descriptor rewrites outside these bindings, and unrelated globals inventory work.
This adds Node's global alias plus legacy Annex B escape/unescape globals, including descriptor/name/length behavior, rebound calls, %uXXXX handling, and Symbol TypeErrors.
Activity
andrewtdiz commentedon Jun 5, 2026
I am taking this issue.
Planned PR cut: add the missing Node-compatible global bindings for bare
escape/unescapeandglobal, then cover them with focused globals parity fixtures. Non-goals: broader URL/querystring behavior changes, global object descriptor rewrites outside these bindings, and unrelated globals inventory work.fix(globals): legacy escape()/unescape() + Node `global` alias (#4511) (
andrewtdiz commentedon Jun 5, 2026
Opened PR: #4545
This adds Node's
globalalias plus legacy Annex Bescape/unescapeglobals, including descriptor/name/length behavior, rebound calls,%uXXXXhandling, and Symbol TypeErrors.Validation on the final rebased branch:
cargo fmt --all -- --checkgit diff --check origin/main..HEAD./scripts/check_file_size.shjq empty test-parity/known_failures.jsonenv RUSTC_WRAPPER= TMPDIR=$PWD/target/tmp CARGO_BUILD_JOBS=1 cargo check -q -p perry-runtime -p perry-hir -p perry-codegennode-suite/globals/legacy-escape-global: 1 pass / 0 parity fail / 0 compile fail (parity_report_20260605_075255.json)node-suite/globals/global-functions: 1 pass / 0 parity fail / 0 compile fail (parity_report_20260605_075512.json)node-suite/globals: 86 pass / 0 parity fail / 0 compile fail / 0 skipped (parity_report_20260605_075659.json)