Skip to content

🐛 Bug Report: ws@3.14.0 crashes on connection in WSGateway.processConnectionRequest reading subscriber.contextKeys.length #10124

@paul-github-1

Description

@paul-github-1

📜 Description

After upgrading self-hosted Novu Community Edition from 3.11.0 to 3.14.0, websocket connections started failing immediately.

The ws container crashes on each connection attempt with:

/usr/src/app/apps/ws/dist/socket/ws.gateway.js:112
const contextDisplay = subscriber.contextKeys.length === 0 ? 'no context' : subscriber.contextKeys.join(', ');
                                                      ^

TypeError: Cannot read properties of undefined (reading 'length')
    at WSGateway.processConnectionRequest (/usr/src/app/apps/ws/dist/socket/ws.gateway.js:112:55)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

I believe the line of code is here:

const contextDisplay = subscriber.contextKeys.length === 0 ? 'no context' : subscriber.contextKeys.join(', ');

The container exits and restarts after each failed connection.

Environment

  • Self-hosted Novu Community Edition via Docker Compose
  • Upgrade path: 3.11.0 -> 3.14.0
  • Services upgraded together: api, worker, ws, dashboard
  • Mongo + Redis unchanged
  • Live app uses latest @novu/js and connects through Inbox/session flow

Important debugging detail

I decoded the websocket JWT used by the client, and it does include contextKeys:

{
  "_id": "<obfuscated>",
  "firstName": "<obfuscated>",
  "lastName": "<obfuscated>",
  "email": "<obfuscated>",
  "organizationId": "<obfuscated>",
  "environmentId": "<obfuscated>",
  "subscriberId": "<obfuscated>",
  "contextKeys": ["app:my_app"],
  "iat": 1772340172,
  "exp": 1773636172,
  "aud": "widget_user",
  "iss": "novu_api"
}

So this does not appear to be a simple case of the client sending an old token without contextKeys.

What I tested

  • Logging out and back in
  • Incognito / fresh session
  • Updating the live app’s Novu client usage
  • Passing explicit context from the live app

The issue persisted.

Likely issue

Either:

  • ws is assuming subscriber.contextKeys is always present without guarding it, or
  • the verified JWT payload is being transformed in a way that drops contextKeys before that line

Given the decoded token already contains contextKeys, this looks like a server-side regression in ws.

Suggested fix

Guard against undefined before using the field, e.g. default to []:

const contextKeys = subscriber.contextKeys ?? [];
connection.data.contextKeys = contextKeys;
const contextDisplay =
  contextKeys.length === 0 ? 'no context' : contextKeys.join(', ');

Workaround

Rolling back to 3.11.0 restores websocket functionality in this setup.

If you want, I can also give you a shorter “minimal repro” version of this issue for GitHub.

👟 Reproduction steps

  1. Upgrade novu self-hosted from 3.11.0 to 3.14.0
  2. Use a live app with @novu/js 3.14.1
  3. See DevTools: websocket connection doesn't work

👍 Expected behavior

ws should not crash during connection handling. At minimum, it should safely handle missing/undefined contextKeys instead of throwing.

👎 Actual Behavior with Screenshots

ws crashes during processConnectionRequest, killing realtime connections entirely.

Novu version

3.14.0

npm version

No response

node version

20.19.2

📃 Provide any additional context for the Bug.

No response

👀 Have you spent some time to check if this bug has been raised before?

  • I checked and didn't find a similar issue

🏢 Have you read the Contributing Guidelines?

Are you willing to submit PR?

None

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions