Skip to content

Large-bundle regression on main: async module init dies with "value is not a function" before first render #5975

Description

@proggeramlug

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:

  1. 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.
  2. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions