Skip to content

fix(runtime): bump Bun to 1.4.0 to fix Stagehand/Browserbase WebSocket upgrades - #7180

Open
reddynitish wants to merge 2 commits into
simstudioai:stagingfrom
reddynitish:fix/5629-bun-websocket-upgrade
Open

fix(runtime): bump Bun to 1.4.0 to fix Stagehand/Browserbase WebSocket upgrades#7180
reddynitish wants to merge 2 commits into
simstudioai:stagingfrom
reddynitish:fix/5629-bun-websocket-upgrade

Conversation

@reddynitish

@reddynitish reddynitish commented Aug 27, 2026

Copy link
Copy Markdown

Summary

  • apps/sim runs entirely under Bun in production (docker/app.Dockerfile boots apps/sim/bootstrap.js with bun, not node). Bun 1.3.x never fired the 'upgrade' event for a genuine 101 WebSocket handshake response — it misrouted through 'response' instead, so any outbound WebSocket client threw Unexpected server response: 101 for a handshake that had actually succeeded.
  • This is the root cause of the Stagehand "Run Agent" block failing to open a Browserbase session: Playwright's CDP transport (which Stagehand uses) inlines its own WebSocket client rather than resolving the top-level ws package, so it hits Bun's node:http-compat layer directly and trips this exact bug. Confirmed against the upstream report: oven-sh/bun#31792 (duplicate of feat(pi): optional multi-provider web search for the coding agent #5951, fixed via #28114/#31800), fixed in Bun 1.4.0 (released 2026-08-20).
  • Bumps the pinned Bun version 1.3.14 → 1.4.0 everywhere it's referenced: root packageManager, every workspace engines.bun floor, all four Dockerfiles, every CI workflow's bun-version, and the Pi sandbox image's mirrored PI_BUN_VERSION pin.
  • Adds two audits (auto-picked-up by bun run check:audits):
    • scripts/check-bun-websocket-upgrade.ts — a runtime probe (raw TCP responder + node:http client, no ws dependency) that fails when the current Bun binary misclassifies a successful 101 upgrade, passes once fixed. Verified: fails on 1.3.14, passes on 1.4.0.
    • scripts/check-bun-version-pins.ts — asserts every Bun version pin in the repo agrees with the root packageManager field, so a future bump can't silently miss one of them (a previous 1.3.13 → 1.3.14 bump did exactly that to the Pi sandbox mirror, and needed a follow-up commit).

Fixes #5629

Type of Change

  • Bug fix

Testing

Exact commands run locally, on Windows, under both Bun versions:

  • bunx vitest run app/api/tools/file/manage/route.test.ts — not applicable to this change; full apps/sim suite run instead:
  • cd apps/sim && bunx vitest run2354 files / 34888 tests: 34819 passed, 46 skipped, 23 failed. Verified the same 23 failures across the same 6 files occur identically on Bun 1.3.14 (pre-bump baseline) — all pre-existing Windows-environment issues (spawnSync('/bin/bash') unavailable, a Windows drive-letter path bug in a test helper, a : in a generated filename) unrelated to this change.
  • bun run check:bun-websocket-upgradePASS on 1.4.0, FAIL on 1.3.14 (verified both ways — this is the regression guard).
  • bun run check:bun-version-pinsPASS. Verified it actually catches drift by temporarily reverting the Pi sandbox pin and a Dockerfile tag; both were caught, then restored.
  • bun run check:native-typecheckPASS.
  • bunx turbo run type-check --filter=@sim/app (tsc --noEmit) — PASS.
  • bunx biome check on all changed/new files — PASS.
  • bun run check:audits (full suite) — 33 passed, 5 failed. Confirmed all 5 failures (check:skills, check:tool-registry-boundary, check:desktop-bridge, check:api-validation:strict, check:utils) are pre-existing on a clean, unmodified upstream/staging checkout (verified via git stash + re-run) — none touch files this PR changes.
  • bun install --frozen-lockfile under 1.4.0 — PASS, bun.lock unchanged (a plain bun install under the new binary drifted unrelated dependency versions on first attempt; reverted and re-verified frozen-lockfile installs cleanly instead, so no dependency versions changed, only the engine pin).
  • Full apps/sim production build (bun run build) — UNVERIFIED on this machine: blocked by an unrelated, pre-existing Windows-only bug in lib/execution/sandbox/bundles/build.ts (a Windows backslash path gets corrupted when interpolated into a generated import string, independent of Bun version — confirmed identical failure on 1.3.14). This step is exercised by CI's Linux runners on every PR, so it isn't blocked there.

An independent adversarial review (in place of Codex, which isn't installed on this machine) verified the root cause and fix directly by reproducing the Bun 1.3.14/1.4.0 client/server behavior matrix itself, and caught one real miss now fixed in this PR: apps/sim/scripts/pi-sandbox-packages.ts's PI_BUN_VERSION constant (originally missed because it's a .ts file, outside the .json/.toml/Dockerfile/.yml grep scope used for the initial sweep — which is exactly the class of gap check:bun-version-pins now closes).

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos

N/A — runtime/infrastructure fix, no UI change.

…t upgrades

apps/sim runs entirely under Bun in production. Bun 1.3.x never fired the
`'upgrade'` event for a genuine 101 WebSocket handshake response — it
misrouted through `'response'` instead, so any outbound WebSocket client
(Playwright's inlined CDP transport, which Stagehand uses to connect to
Browserbase, chrome-devtools-mcp, puppeteer) threw "Unexpected server
response: 101" for a handshake that had actually succeeded. Fixed upstream
in Bun 1.4.0 (oven-sh/bun#31792, oven-sh/bun#28114).

- Bump the pinned Bun version (1.3.14 -> 1.4.0) everywhere it's referenced:
  root packageManager, every workspace engines.bun floor, all Dockerfiles,
  every CI workflow's bun-version, and the Pi sandbox image's mirrored pin.
- Add scripts/check-bun-websocket-upgrade.ts: a runtime probe (raw TCP
  responder + node:http client) that fails on a Bun whose client
  misclassifies a 101 upgrade, and passes once it's fixed. Verified it fails
  on 1.3.14 and passes on 1.4.0.
- Add scripts/check-bun-version-pins.ts: asserts every Bun version pin in the
  repo agrees with the root packageManager field, so a future bump can't
  silently miss one of them the way the 1.3.13 -> 1.3.14 bump missed the Pi
  sandbox mirror.

Fixes simstudioai#5629

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@reddynitish
reddynitish requested a review from a team as a code owner August 27, 2026 22:53
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

@reddynitish is attempting to deploy a commit to the Sim Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR consistently upgrades Bun from 1.3.14 to 1.4.0 across production images, CI workflows, workspace engine declarations, and the Pi sandbox to restore outbound WebSocket upgrades.

  • Adds a runtime regression probe for correct HTTP 101 upgrade-event handling.
  • Adds an automatically discovered audit that checks duplicated Bun pins against the root packageManager version.
  • Documents that Bun 1.4.0 retains the existing fetch timeout behavior.

Confidence Score: 4/5

The PR appears safe to merge, with only a non-blocking logging-convention issue in the new audit scripts.

The Bun pins are consistent across the changed runtime and build surfaces, the audits are wired into CI, and no blocking compatibility or lifecycle failure remains; only direct console usage needs cleanup.

Files Needing Attention: scripts/check-bun-version-pins.ts, scripts/check-bun-websocket-upgrade.ts

Important Files Changed

Filename Overview
scripts/check-bun-version-pins.ts Adds comprehensive consistency checks for current Bun pin surfaces, but uses direct console output contrary to repository logging conventions.
scripts/check-bun-websocket-upgrade.ts Adds a focused loopback regression probe for Bun's HTTP upgrade handling; its direct console output shares the logging-convention issue.
package.json Updates the canonical Bun version and registers both new checks for automatic audit discovery.
docker/app.Dockerfile Moves the production Sim runtime to Bun 1.4.0, addressing the WebSocket compatibility defect described by the PR.
apps/sim/scripts/pi-sandbox-packages.ts Keeps the Pi sandbox's mirrored Bun installation version aligned with the root pin.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Root[Root packageManager: bun@1.4.0] --> Audit[Version-pin audit]
  Audit --> Engines[Workspace engines.bun]
  Audit --> Docker[Docker image tags]
  Audit --> CI[CI bun-version inputs]
  Audit --> Sandbox[Pi sandbox Bun version]
  Bun[Bun 1.4.0 runtime] --> Probe[WebSocket upgrade probe]
  Probe --> Event[101 response emits upgrade]
  Event --> Browser[Stagehand / Browserbase CDP connection]
Loading

Reviews (1): Last reviewed commit: "fix(runtime): bump Bun to 1.4.0 to fix S..." | Re-trigger Greptile

Comment thread scripts/check-bun-version-pins.ts Outdated
Comment on lines +28 to +31
console.error(
`Bun version pin audit failed: root package.json "packageManager" is "${packageManager}", ` +
'expected "bun@<major>.<minor>.<patch>".'
)

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.

P2 Audit scripts bypass logger

The new Bun audits use console.error and console.log instead of the required @sim/logger abstraction, bypassing the repository's standard logging behavior and formatting. The same pattern occurs throughout both new audit scripts.

Context Used: Global coding standards that apply to all files (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Addresses Greptile review on PR simstudioai#7180 — the two new Bun audits used
console.log/console.error directly instead of the repo's createLogger
convention (see apps/sim/scripts/*.ts and
apps/sim/lib/execution/sandbox/bundles/build.ts for the existing pattern).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@reddynitish

Copy link
Copy Markdown
Author

Fixed in 02dc4db. Replaced direct console usage in both Bun audit scripts with the repository logger and re-ran both checks successfully.

@reddynitish

Copy link
Copy Markdown
Author

@simstudioai/deps This is ready for maintainer review when you have a chance. The earlier logging-convention feedback has been addressed in 02dc4db, and I re-ran the Bun WebSocket regression/version-pin checks successfully. Since this updates the repo-wide Bun pin and package-manager/runtime surfaces, I’d especially appreciate a review of the 1.4.0 bump and the regression audits. Happy to make any follow-up changes.

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