Skip to content

fix(dockerfile): pin Bun to 1.3.13-slim to dodge 1.3.14 ARM64 crash - #678

Closed
devxoul wants to merge 1 commit into
mainfrom
fix/bun-arm64-pin-1.3.13
Closed

devxoul wants to merge 1 commit into
mainfrom
fix/bun-arm64-pin-1.3.13

Conversation

@devxoul

@devxoul devxoul commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Background

A bug report from an Apple-silicon (ARM64) host: the container reports a Bun
version, but every attempt to run an external package crashes.

$ bun run dist/src/platforms/webex/cli.js --help
[1]    3 Aborted                 bun run dist/src/platforms/webex/cli.js --help
EXIT: 134

bunx, bun add, and bun run <pkg> all abort with SIGABRT (exit 134) or a
NotDir internal error; even bun upgrade self-fails with StackOverflow. The
agent-messenger CLIs (agent-webex, etc.) were effectively unrunnable inside the
container.

Root cause is upstream Bun, surfaced by our own tag policy. The base image
FROM used the floating oven/bun:1-slim tag, which silently rolled the
base onto Bun 1.3.14. That release has two ARM64 Linux regressions that hit
exactly the external-package launch path:

  • A self-referencing symlink created in createFakeTemporaryNodeExecutable
    (/tmp/bun-node-*/node -> bun -> bun -> ...) -> ELOOP / SIGABRT
    (oven-sh/bun#30711).
  • require()-of-ESM aborting with a PAC IB trap (silent SIGTRAP/SIGABRT)
    (oven-sh/bun#30281).

The fix for #30711 (oven-sh/bun#30713)
is not yet in any stable release, so there is no forward fix to roll to -- the only
remedy today is to stop landing on 1.3.14.

Summary

Pin the base image to an exact patch, oven/bun:1.3.13-slim -- the last
known-good release -- instead of the floating 1-slim tag. Floating tags make
base-image rebuilds non-deterministic; a single upstream patch release can break
every installed agent on the next rebuild, which is exactly what happened here.

The pin lives in one BUN_IMAGE constant that feeds both the prebuilt base
image (buildBaseDockerfile) and the inline dev/test path (renderInlineHead),
so production and dev mode can't drift onto different Bun versions.

The three CI Bun pins (ci.yml, release.yml, base-image.yml) move
1.3.14 -> 1.3.13 so the runner validating/releasing the image uses the same Bun
as the container. They were already pinned (not latest); this just holds them
at the known-good patch and documents why.

What this does NOT do

  • Does not rebuild or publish a new typeclaw-base image. That happens via
    the Release workflow; this PR only changes what the next release will build.
  • Does not touch the affected agent folders on hosts -- they pick up the fix
    on their next typeclaw start once a release ships the new base.
  • Does not work around the upstream bug in our own code; it avoids the broken
    Bun version entirely.

Review notes

  • Load-bearing change: src/init/dockerfile.ts BUN_IMAGE = oven/bun:1.3.13-slim.
    Invariant to verify -- bun run scripts/emit-base-dockerfile.ts | grep ^FROM
    now prints FROM oven/bun:1.3.13-slim.
  • The drift guard in dockerfile.test.ts asserts base and per-agent Dockerfiles
    share the same FROM; tests updated to the new tag. The two
    not.toContain('FROM oven/bun:...') assertions were widened to FROM oven/bun:
    so they stay meaningful regardless of the pinned patch.
  • The two start.test.ts "stale Dockerfile" input fixtures still use 1-slim on
    purpose -- they represent an old on-disk Dockerfile that refreshDockerfile
    overwrites.
  • Bump to the next stable once install: stop nested --bun from self-referencing its node shim oven-sh/bun#30713 lands; the BUN_IMAGE comment
    flags that follow-up.

The base image FROM used the floating `oven/bun:1-slim` tag, which rolled
onto Bun 1.3.14. On ARM64 Linux that release aborts with SIGABRT whenever
the agent launches an external package via `bunx`, `bun add`, or
`bun run <pkg>` — a self-referencing symlink in
`createFakeTemporaryNodeExecutable` (oven-sh/bun#30711) plus a
require()-of-ESM PAC IB trap (oven-sh/bun#30281). The container could
report a Bun version but every external-package launch crashed, so e.g.
agent-messenger CLIs were unrunnable on Apple-silicon hosts.

Pin to an exact patch (`oven/bun:1.3.13-slim`, the last known-good
release) instead of the floating tag so base-image rebuilds stay
deterministic. A single `BUN_IMAGE` constant feeds both the prebuilt base
image (`buildBaseDockerfile`) and the inline dev path (`renderInlineHead`),
so production and dev mode cannot drift. The three CI Bun pins
(ci/release/base-image workflows) move 1.3.14 -> 1.3.13 to match.

Bump to the next stable once oven-sh/bun#30713 lands.
@devxoul
devxoul requested a review from typeey as a code owner June 6, 2026 16:30

@typeey typeey Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pin is applied through the shared Dockerfile constant that feeds both inline and base-image generation, and the updated assertions cover the important drift cases. The matching workflow Bun pins and the existence of the oven/bun:1.3.13-slim amd64/arm64 image make this safe to land from a code-review perspective.

@typeey
typeey Bot removed the request for review from typeey June 6, 2026 16:31
@devxoul

devxoul commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

Closing: this fix is incorrect. Reproduced the crash on ARM64/OrbStack and proved via strace that it is NOT a Bun version regression — Bun 1.3.13 crashes identically. The real root cause is the bwrap sandbox's --tmpfs /proc: the spawned child of bunx reads /proc/self/fd and /proc/self/maps which don't exist under the empty tmpfs proc, surfaced as Bun's NotDir. Fix moves to src/sandbox (opt-in real-proc strategy). Superseded by a follow-up PR.

@devxoul devxoul closed this Jun 6, 2026
@typeey

typeey Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Got it — thanks for the repro and strace. That makes sense; the Bun pin isn’t the root cause here. I’ll treat this as superseded by the sandbox-side fix in src/sandbox.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant