Symptom
A large esbuild-bundled CLI app (13 MB minified, lazy var X = y(() => {...}) module wrappers, React/ink TUI) compiled with current origin/main:
--version prints correctly (module graph loads, sync init fine);
- launching the TUI exits within seconds, before any render, with:
Uncaught (in promise) TypeError: value is not a function
at <anonymous>
(twice — two rejected init promises; -Os build, so no symbol names).
Regression evidence
The same bundle compiled with a perry built from the older tui-input-era base plus the cherry-picked recent fixes (#5913, #5921, #5926, #5964) runs the full app: renders, completes its network checks, drives its interactive flows end-to-end. So the app code and those four fixes are sound — something else in the main lineage between that base and origin/main breaks the bundle's async module initialization.
History of the same window (same app, tracked while the four fixes landed): main formerly hung silently pre-render; before that it crashed on a lazy-module enum read (reading 'COMPARATOR'). With #5921 merged those turned into this crisp double TypeError: value is not a function — the failure has been moving through the async-init path as fixes land, consistent with one remaining mis-lowering in the async/CPS lineage.
Suspects / next steps
Candidate window: the async-transform/runtime rework line — #5831 (JS-loop-driven current-thread runtime), #5854 (CPS async class methods + nested async closures), #5867 (promise reaction handler slots), #5885 (switch inside async/generator state machines).
Two practical attacks:
- Name the callee: a
PERRY_THROW_BT-gated native backtrace in js_typeerror_new for * is not a function messages (runtime-only change, cheap to iterate via staticlib relink) — identifies which init closure calls a non-function.
- Bisect main across the candidate PRs compiling the bundle (~35 min/step, so the 4-5 candidates above first rather than a full git-bisect).
I can supply compile logs / run traces for candidate builds on request; the bundle itself is a public npm package's bundled entry (reproducible from its published tarball).
Symptom
A large esbuild-bundled CLI app (13 MB minified, lazy
var X = y(() => {...})module wrappers, React/ink TUI) compiled with currentorigin/main:--versionprints correctly (module graph loads, sync init fine);(twice — two rejected init promises;
-Osbuild, so no symbol names).Regression evidence
The same bundle compiled with a perry built from the older
tui-input-era base plus the cherry-picked recent fixes (#5913, #5921, #5926, #5964) runs the full app: renders, completes its network checks, drives its interactive flows end-to-end. So the app code and those four fixes are sound — something else in the main lineage between that base andorigin/mainbreaks the bundle's async module initialization.History of the same window (same app, tracked while the four fixes landed): main formerly hung silently pre-render; before that it crashed on a lazy-module enum read (
reading 'COMPARATOR'). With #5921 merged those turned into this crisp doubleTypeError: value is not a function— the failure has been moving through the async-init path as fixes land, consistent with one remaining mis-lowering in the async/CPS lineage.Suspects / next steps
Candidate window: the async-transform/runtime rework line — #5831 (JS-loop-driven current-thread runtime), #5854 (CPS async class methods + nested async closures), #5867 (promise reaction handler slots), #5885 (switch inside async/generator state machines).
Two practical attacks:
PERRY_THROW_BT-gated native backtrace injs_typeerror_newfor* is not a functionmessages (runtime-only change, cheap to iterate via staticlib relink) — identifies which init closure calls a non-function.I can supply compile logs / run traces for candidate builds on request; the bundle itself is a public npm package's bundled entry (reproducible from its published tarball).