Repository navigation
Conversation
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.
There was a problem hiding this comment.
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.
|
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 |
|
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 |
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.
bunx,bun add, andbun run <pkg>all abort with SIGABRT (exit 134) or aNotDirinternal error; evenbun upgradeself-fails withStackOverflow. Theagent-messenger CLIs (
agent-webex, etc.) were effectively unrunnable inside thecontainer.
Root cause is upstream Bun, surfaced by our own tag policy. The base image
FROMused the floatingoven/bun:1-slimtag, which silently rolled thebase onto Bun 1.3.14. That release has two ARM64 Linux regressions that hit
exactly the external-package launch path:
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 lastknown-good release -- instead of the floating
1-slimtag. Floating tags makebase-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_IMAGEconstant that feeds both the prebuilt baseimage (
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) move1.3.14 -> 1.3.13so the runner validating/releasing the image uses the same Bunas the container. They were already pinned (not
latest); this just holds themat the known-good patch and documents why.
What this does NOT do
typeclaw-baseimage. That happens viathe Release workflow; this PR only changes what the next release will build.
on their next
typeclaw startonce a release ships the new base.Bun version entirely.
Review notes
src/init/dockerfile.tsBUN_IMAGE = oven/bun:1.3.13-slim.Invariant to verify --
bun run scripts/emit-base-dockerfile.ts | grep ^FROMnow prints
FROM oven/bun:1.3.13-slim.dockerfile.test.tsasserts base and per-agent Dockerfilesshare the same
FROM; tests updated to the new tag. The twonot.toContain('FROM oven/bun:...')assertions were widened toFROM oven/bun:so they stay meaningful regardless of the pinned patch.
start.test.ts"stale Dockerfile" input fixtures still use1-slimonpurpose -- they represent an old on-disk Dockerfile that
refreshDockerfileoverwrites.
BUN_IMAGEcommentflags that follow-up.