Skip to content

Fix app dev crash on malformed /extensions WebSocket frames - #9039

Open
isaacroldan wants to merge 1 commit into
mainfrom
torrent/cli-1-app-dev-crashes-when-an-extensions-webso
Open

isaacroldan wants to merge 1 commit into
mainfrom
torrent/cli-1-app-dev-crashes-when-an-extensions-webso

Conversation

@isaacroldan

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

shopify app dev exits when a client of the /extensions WebSocket breaks the WebSocket protocol, for example with a frame larger than maxPayload. The local proxy stops with it.

getConnectionDoneHandler registers a message listener on each socket, but no error listener. On a protocol error, ws emits error on the socket. With no listener, Node throws it as an unhandled error (RangeError: Max payload size exceeded) and the process exits.

WHAT is this pull request doing?

  • Adds an error listener to each /extensions socket. It logs the error with outputDebug. ws already closes the failing connection (code 1009 for an oversized frame), so the server and the other clients keep working.
  • Adds regression tests in handlers.test.ts:
    • An error event on a connected socket does not throw and is logged.
    • With a real server, a client that sends an oversized frame is closed with 1009. A new client can then connect and send a dispatch, and an existing client receives it.
  • Adds a patch changeset for @shopify/app.

How to manually test your changes?

  1. Run shopify app dev --verbose in an app with a UI extension.
  2. Find the local server port in the output, then connect to ws://localhost:<port>/extensions with a WebSocket client and send a frame larger than 100 MiB. With ws in Node:
    const ws = new (require('ws'))('ws://localhost:<port>/extensions')
    ws.on('open', () => ws.send(Buffer.alloc(101 * 1024 * 1024)))
    ws.on('close', (code) => console.log('closed', code))
  3. Before this change, app dev exits with RangeError: Max payload size exceeded. After this change, the client prints closed 1009, app dev keeps running, and the verbose output shows Websocket connection error: Max payload size exceeded.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

getConnectionDoneHandler registered a message listener on each socket
but no error listener. When a client breaks the WebSocket protocol, for
example with a frame larger than maxPayload, ws emits 'error' on the
socket. With no listener, Node throws it as an unhandled error and
`app dev` exits.

Log the error with outputDebug. ws already closes the failing
connection (1009 for an oversized frame), so the server and the other
clients keep working.

Co-authored-by: isaac.roldan <isaac.roldan@shopify.com>
@github-actions github-actions Bot added the Area: @shopify/app @shopify/app package issues label Oct 29, 2026
@isaacroldan
isaacroldan marked this pull request as ready for review October 29, 2026 12:05
@isaacroldan
isaacroldan requested a review from a team as a code owner October 29, 2026 12:05

This branch has not been deployed

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

Labels

Area: @shopify/app @shopify/app package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant