Locally, everything worked. In production on Vercel, the connection indicator went green, “Status: Connected”, and then nothing. The host created a game, a player joined, and the host’s screen stayed empty. No error. No message. An open connection to silence.
What I believed
That it was a network or security problem. Production sits behind a domain, with a content security policy, and WebSockets need the door opened for them: the ws:// and wss:// protocols have to be allowed. I checked, fixed, redeployed. Still green, still empty.
Then I suspected the environment variables, because they differ between my machine and the server. I added .trim() everywhere, just in case. Redeployed. Green, empty.
What it was
PartyKit organises connections by “parties”, that is, by rooms: each room type has a name, and the client has to say which one it wants to talk to. The connection constructor accepted a party parameter, and I was not passing it. Locally, the default value landed on the right room. In production, it landed on an empty room, which politely accepted the connection and had nobody listening.
// before: connected to a room that does not exist
new PartySocket({ host, room: code });
// after: connected to the room that runs the game
new PartySocket({ host, room: code, party: 'game' });
One line. The fix is dated 13 February in the CHANGELOG, labelled “critical fix”. I could have written “humbling fix”.
What I take from it
The signal that misled me was the green light. “Connected” meant the WebSocket handshake had succeeded, not that anyone was listening on the other side. An indicator that reassures without guaranteeing anything is worse than no indicator: it points the search at everything except itself.
The AI tool had written the client and the server, consistent with each other, with that default value that worked on my machine. There was no reason for it to notice what production would change, and I had not asked. The useful question, which I now ask before every deployment, fits in one sentence: what is different over there, and where does it enter the code?
A green light says the door is open. It does not say anyone is behind it.
Get the journal by email
About one entry a week. What I build, what breaks, what I learn. No promotion, one-click unsubscribe.
You can also follow the RSS feed.