📜 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
- Upgrade novu self-hosted from 3.11.0 to 3.14.0
- Use a live app with @novu/js 3.14.1
- 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?
🏢 Have you read the Contributing Guidelines?
Are you willing to submit PR?
None
📜 Description
After upgrading self-hosted Novu Community Edition from
3.11.0to3.14.0, websocket connections started failing immediately.The
wscontainer crashes on each connection attempt with:I believe the line of code is here:
novu/apps/ws/src/socket/ws.gateway.ts
Line 161 in 05a978e
The container exits and restarts after each failed connection.
Environment
3.11.0->3.14.0api,worker,ws,dashboard@novu/jsand connects through Inbox/session flowImportant 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
contextfrom the live appThe issue persisted.
Likely issue
Either:
wsis assumingsubscriber.contextKeysis always present without guarding it, orcontextKeysbefore that lineGiven the decoded token already contains
contextKeys, this looks like a server-side regression inws.Suggested fix
Guard against undefined before using the field, e.g. default to
[]:Workaround
Rolling back to
3.11.0restores 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
👍 Expected behavior
wsshould not crash during connection handling. At minimum, it should safely handle missing/undefinedcontextKeysinstead of throwing.👎 Actual Behavior with Screenshots
wscrashes duringprocessConnectionRequest, 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?
🏢 Have you read the Contributing Guidelines?
Are you willing to submit PR?
None