Skip to content

Possible Bun 1.4.1 Android/Bionic compile regression with splitting:true #42837

Closed

Description

@monag144

Summary

We isolated a reproducible difference between Bun 1.4.0 and Bun 1.4.1 when compiling OpenCode 1.18.31 for an Android/Bionic/Termux environment.

The same OpenCode source and dependency tree behaves correctly when run directly under both Bun 1.4.0 and Bun 1.4.1. The failure appears only in the Bun 1.4.1 compiled/embedded executable path when splitting:true is enabled.

Observed matrix

  • OpenCode 1.18.31 source run directly under Bun 1.4.0: PASS (/api/reference and /api/agent HTTP 200)
  • Same source run directly under Bun 1.4.1: PASS
  • Bun 1.4.0 compiled Android/Bionic candidate: PASS
  • Bun 1.4.1 compiled with minify:true, splitting:true: FAIL (/api/reference and /api/agent HTTP 500)
  • Bun 1.4.1 compiled with minify:false, splitting:true: FAIL
  • Bun 1.4.1 compiled with minify:true, splitting:false: PASS (/api/config, /api/reference, /api/agent HTTP 200)
  • Fresh Bun 1.4.1 control with normal splitting:true reproduced the failure

The failing executable reaches an OpenCode internal exception of the form:

TypeError: undefined is not an object (evaluating 'a.name')

Earlier investigation initially suggested a malformed OpenCode reference object, but the A/B controls above challenged that diagnosis: direct source execution passes under Bun 1.4.1, and disabling compile-time splitting makes the compiled 1.4.1 artifact pass without any OpenCode source patch.

Environment

  • Android / Termux
  • Bionic libc environment
  • OpenCode 1.18.31
  • Bun 1.4.0 and 1.4.1 compared against the same reconstructed source/dependency tree
  • @androidtui/core 0.5.5

Known-good workaround

Compile OpenCode 1.18.31 with Bun 1.4.1 and:

minify:true, splitting:false

Qualified no-split artifact:

  • SHA256: 02367cb9fa073ab37acadd6d4ca35db590f7fd4c775147541104ec604fee6e4e
  • Size: 188,614,920 bytes

Bun 1.4.0 compiled control artifact:

  • SHA256: 26c7610ef19d4982dbd72ed3db7663813543bfcaf4d99834665df1f365bb9905

Interpretation

Current evidence suggests a Bun 1.4.1 compile-time splitting regression on this Android/Bionic path, rather than an ordinary OpenCode source-level defect or minification issue.

We have not yet reduced this to a tiny standalone Bun reproducer outside the OpenCode build tree, so this report is intentionally scoped as a possible Bun regression rather than a universal claim.

If useful, I can provide the exact OpenCode build settings/source locations used to produce the A/B candidates.

Activity

  1. robobun commented on Sep 16, 2026

    @robobun
    Collaborator

    I tried to reproduce this with the stock OpenCode 1.18.31 source and Bun 1.4.1 on Linux x64. I do not have an Android device, so I could not run a bun-linux-aarch64-android executable.

    Bun version: 1.4.1 (release build from GitHub) on linux x64

    Attempt 1: Build OpenCode 1.18.31 with its own build script. The script uses minify: true, splitting: true and compile (see packages/opencode/script/build.ts). Then start the compiled executable and call the agent and config routes.

    $ git clone --depth 1 --branch v1.18.31 https://github.com/anomalyco/opencode.git
    $ cd opencode && bun install
    $ cd packages/opencode
    $ bun run script/build.ts --single --skip-embed-web-ui --skip-install
    Loaded models.dev snapshot
    building opencode-linux-x64
    Running smoke test: dist/opencode-linux-x64/bin/opencode --version
    Smoke test passed: 0.0.0--202609160107
    
    $ dist/opencode-linux-x64/bin/opencode serve --port 14141 --hostname 127.0.0.1 &
    opencode server listening on http://127.0.0.1:14141
    
    $ curl -s -w "\nHTTP %{http_code}\n" http://127.0.0.1:14141/global/health
    {"healthy":true,"version":"0.0.0--202609160107"}
    HTTP 200
    
    $ curl -s -w "\nHTTP %{http_code}\n" http://127.0.0.1:14141/config
    {"$schema":"https://opencode.ai/config.json","command":{},"plugin":[],"username":"unknown","mode":{},"agent":{}}
    HTTP 200
    
    $ curl -s -w "\nHTTP %{http_code}\n" http://127.0.0.1:14141/agent
    [{"name":"build","description":"The default agent. Executes tools based on configured permissions.","mode":"primary","native":true,"permission":[...]}, ...]
    HTTP 200

    Expected HTTP 500 with TypeError: undefined is not an object (evaluating 'a.name'). Got HTTP 200 on all routes.

    Attempt 2: Search the OpenCode 1.18.31 source for the routes in the report.

    $ grep -rn '/api/agent\|/api/reference\|"/reference"' packages/opencode/src
    (no matches)

    The stock source has no /api/reference or /api/agent route. The tree that fails is a modified one (@androidtui/core is a fork of @opentui/core).

    Conclusion: The stock OpenCode 1.18.31 build with Bun 1.4.1, splitting: true and compile works on Linux x64. I cannot tell from the report alone whether the failure comes from the Android runtime, from the modified source tree, or from a bundler change between 1.4.0 and 1.4.1.

    To make progress, please provide:

    1. The exact Bun.build options and the changes to the source tree (the /api/* routes, the @androidtui/core swap, the target value).
    2. The full stack trace of the TypeError. Build with minify: false and sourcemap: "linked" (or "inline") so the trace has file names and the real variable name, not a.
    3. A check of the same build with --target=bun-linux-x64 (or your host target) on a Linux machine. If it fails there too, the Android runtime is not the cause.
    4. If possible, a small standalone reproducer. The module that throws at a.name, its importers, and whether that module is reached through import() would already narrow this a lot. Several import() and require() interop changes landed in 1.4.1 (for example bundler: tree-shake unobserved exports of import() / require() targets #32557, bundler: give a split import() of a lifted CommonJS module its namespace as default #41231, bundler: wrap a split import() with __toESM when the target is CommonJS at link time #41237, bundler: read .default of a split require() whose target is CommonJS at link time #41243), so a reduced case around the failing dynamic import is the most useful thing.
  2. martinstiago commented on Sep 18, 2026

    @martinstiago

    Confirming this reproduces on stock opencode on macOS (darwin-arm64) — it's not Android/Bionic- or fork-specific.

    (Context: this also blocks anomalyco/opencode#44946, which bumps opencode's embedded Bun to 1.4.x — see the "Blocker" note there. Posting here since the root cause lives in Bun's bundler.)

    Setup: unmodified anomalyco/opencode dev (Sep 18, b02acc1), only change is packageManager: [email protected]. Built with its own build script (packages/opencode/script/build.ts: Bun.build + compile, minify: true, splitting: true).

    Matrix:

    Configuration Result
    Bun 1.3.14, compiled binary (stock v1.18.31 release) PASS — full agent turn works
    Bun 1.4.1, compiled binary, splitting: true FAIL — first agent turn crashes
    Bun 1.4.2, compiled binary, splitting: true FAIL — same crash
    Bun 1.4.2, compiled binary, splitting: false PASS — full agent turn works
    Bun 1.4.1/1.4.2, running from source (no compile) PASS on both

    Crash (with --sourcemaps linked, hence real file names):

    TypeError: undefined is not an object (evaluating 'node.name')
        at resolve (packages/core/src/effect/layer-node.ts:241:45)   // replacementMap.get(node.name) ?? node
        at recur (layer-node.ts:185:28)                              // options.resolve?.(node) ?? node
        at map (native)
        at <anonymous> (layer-node.ts:239:57)                        // node.dependencies.map(context.visit)
        ...
        at SystemPrompt.environment (src/session/prompt.ts:1259)
    

    A node in the Effect layer graph is undefined — consistent with cross-chunk
    module-init ordering under ESM splitting in the compiled bundle. Not reproducible from
    source on the same Bun versions.

    One important note on reproduction: the crash only fires on an actual agent turn
    (prompt → system-prompt build → layer resolution). Route-level smoke tests
    (/health, /config, /agent) all return 200 on a broken binary — that may explain why
    the stock-source repro attempt above came back clean.

    Happy to help narrow further — the hoist/walk code in layer-node.ts around those
    lines is the failing site, and I can test candidate fixes or a minimized repro on darwin-arm64.

  3. Jarred-Sumner commented on Sep 26, 2026

    @Jarred-Sumner
    Collaborator

    Fixed in #42695

  4. robobun commented on Sep 26, 2026

    @robobun
    Collaborator

    This is the same bug as #42632: with splitting: true, a chunk shared by several entry points could print an import cycle in the wrong order, so a hoisted var was read as undefined (node.name in layer-node.ts).

    #42695 fixes it and is merged into main (97246d0). I verified on main: test/bundler/bundler_splitting.test.ts passes, including the tests for this cycle. The fix is not in a tagged release yet (latest tag is 1.4.2). It is in canary (bun upgrade --canary) and ships in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions