Skip to content

fix(build-tools): stop one WebSocket message from crashing the self-hosted API - #5988

Merged
adrians5j merged 1 commit into
nextfrom
claude/fix-ws-bufferutil-crash
Oct 13, 2026
Merged

adrians5j merged 1 commit into
nextfrom
claude/fix-ws-bufferutil-crash

Conversation

@adrians5j

@adrians5j adrians5j commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

On a self-hosted API, any incoming WebSocket message of 32 bytes or more crashed the API process with TypeError: bufferUtil.unmask is not a function. The process exited, and the API stayed down until it was restarted.

Cause

The function bundle config (build-tools/bundling/function/createRsbuildConfig.js) set resolve.fallback: { bufferutil: false } to leave out ws's optional native bufferutil module. A false fallback makes rspack bundle an empty module in its place. ws loads bufferutil inside a try/catch and falls back to its own JavaScript only when the require throws. The empty module loads fine, so ws switched mask/unmask to bufferUtil.mask/bufferUtil.unmask, which are undefined. Client frames are always masked, and ws uses the native unmask for payloads of 32 bytes or more, so every message that size threw inside the socket's data handler. The ws server runs only in the self-hosted (standalone) API. On AWS, WebSockets go through API Gateway.

Fix

bufferutil is now left out with an IgnorePlugin entry, the same way the config already leaves out jsdom's optional canvas. An ignored module throws MODULE_NOT_FOUND when required, ws catches that, and it keeps its JavaScript implementation. The resolve.fallback entry is removed. bufferutil was the only module the bundle ignored this way.

Testing

  • Before: with the self-hosted API running locally, a 94-byte message to the WebSocket endpoint closed the connection with 1006, and the API returned 503 from then on.
  • After: the rebuilt bundle throws MODULE_NOT_FOUND for bufferutil, and the same message sent three times leaves the API answering 200. The admin's own WebSocket connection still connects and works.
  • 6.5.0 has the same config and the same ws server (api-websockets-server), and its betas are published. The same change for 6.5.0 is fix(build-tools): stop one WebSocket message from crashing the self-hosted API (6.5.0) #5989.

Workspace: wby-next2 · 🧹 MERGE 6.5.0 => NEXT

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved WebSocket compatibility in environments where an optional native component is unavailable, allowing the JavaScript implementation to be used instead.

The API bundle replaced ws's optional native `bufferutil` module with an
empty one (`resolve.fallback: { bufferutil: false }`). ws loads it inside
a try/catch, and an empty module loads without throwing, so ws switched
to `bufferUtil.unmask`, which is undefined. Every client frame is masked,
so any incoming WebSocket message of 32 bytes or more threw
"bufferUtil.unmask is not a function" and took the API process down. On
a self-hosted API that needed no authentication: one message to the
WebSocket endpoint was enough.

bufferutil is now left out with an IgnorePlugin entry instead, like
jsdom's `canvas`. An ignored module throws MODULE_NOT_FOUND when
required, ws catches that, and it keeps its JavaScript mask/unmask.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚓 Slop Cop

✅ Nothing worth flagging. The diff looks consistent with the PR's stated intent and the code-style rules.

Small, focused fix matching its stated intent; no integrity or style issues found.

Automated, non-blocking heads-up from an LLM. It can be wrong — use your judgment. Regenerates on every push.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4a4a2575-0ba3-448c-8b6c-fa4d5b126e0d
📥 Commits

Reviewing files that changed from the base of the PR and between 1a045c5 and 70d199c.

📒 Files selected for processing (1)
  • packages/build-tools/bundling/function/createRsbuildConfig.js

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 3 remain after this review.

📝 Walkthrough

The bundler now ignores ws’s optional bufferutil dependency instead of resolving it to an empty module. This allows ws to use its JavaScript implementation when bufferutil is unavailable.

Changes: ws optional dependency handling

Layer / File(s) Summary
Ignore optional bufferutil dependency
packages/build-tools/bundling/function/createRsbuildConfig.js
The Rsbuild configuration adds an IgnorePlugin scoped to ws and removes the bufferutil fallback.

Priority: ⬆️ High

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: pavel910

Merge Risk: ⚪ Minimal · up to 70d19

The change lets ws use JavaScript masking when bufferutil is unavailable. No merge-blocking risk is evident.

Pre-merge checks · Passed 5
Passed Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the primary change: preventing a WebSocket message from crashing the self-hosted API through a build-tools fix.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@adrians5j
adrians5j merged commit f61e655 into next Oct 13, 2026
19 checks passed
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