Skip to content

Conversation

@francescov1
Copy link
Contributor

@francescov1 francescov1 commented Jan 26, 2026

When using the Agents SDK along with hibernated websockets, partyserver indiscriminately tries to broadcast messages to all connections (from ctx.getWebSockets()), including foreign hibernated sockets accepted via ctx.acceptWebSocket(). Those sockets dont have partyserver's __pk attachment metadata, so reading connection.id throws the following error:

TypeError: Cannot read properties of undefined (reading 'id')
    at WebSocket.get (index.js:119299:38)
    at AgentSessionImpl.broadcast (index.js:119692:117)
    at AgentSessionImpl._setStateInternal (index.js:120183:10)
    at AgentSessionImpl.setState (index.js:120204:10)
    at AgentSessionImpl.ensureOpenCodeSession (index.js:211076:10)
    at async AgentSessionImpl.saveAndSendPrompt (index.js:211898:33)
    at async AgentSessionImpl.handleAgentSessionCreated (index.js:211789:5)

This PR adds logic to detect whether a WebSocket has PartyServer’s __pk attachment and skips non-PartyServer sockets . Also ignores non-PartyServer sockets in webSocketMessage/webSocketClose/webSocketError so we never attempt to rehydrate them into a Connection.

tryGetPartyServerMeta can probably be refined, not too familiar with this repo

@changeset-bot
Copy link

changeset-bot bot commented Jan 26, 2026

🦋 Changeset detected

Latest commit: 7eccf4f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
partyserver Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@threepointone
Copy link
Collaborator

brother what on earth is this PR

@francescov1
Copy link
Contributor Author

@threepointone pls read the description, it fixes a bug from using the Agents SDK with hibernated websockets

Copy link
Collaborator

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, dropped a couple of comments on code that probably shouldn't be there. Let's run CI on this

package.json Outdated
"@cloudflare/vite-plugin": "^1.19.0",
"@cloudflare/vitest-pool-workers": "^0.10.4",
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
"@rolldown/binding-darwin-arm64": "^1.0.0-beta.55",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed to get native rolldown bindings to build locally on Mac (npm run build). Can remove if youd like

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like it broke CI, Ill remove it

{
"name": "partyserver",
"version": "0.1.0",
"version": "0.1.1",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

@threepointone
Copy link
Collaborator

could you revert the changes to package-lock.json as well please?

@francescov1
Copy link
Contributor Author

@threepointone done

@threepointone
Copy link
Collaborator

/oc review

Co-authored-by: threepointone <threepointone@users.noreply.github.com>
@opencode-agent
Copy link
Contributor

PR Review Summary

This PR fixes a real issue when using PartyServer alongside the Agents SDK with hibernated WebSockets. The problem occurs when user code calls ctx.acceptWebSocket() directly (outside PartyServer), creating WebSockets that lack PartyServer's __pk attachment metadata. When PartyServer then tries to broadcast or iterate connections, accessing connection.id throws because __pk is undefined.

What the PR does:

  1. Adds tryGetPartyServerMeta() (connection.ts:41-67) - Safely extracts PartyServer metadata from a WebSocket by directly calling deserializeAttachment() and validating the __pk structure exists with proper id and server strings.

  2. Adds isPartyServerWebSocket() (connection.ts:70-72) - Simple predicate wrapping tryGetPartyServerMeta().

  3. Filters foreign sockets in iteration (connection.ts:218-221) - HibernatingConnectionIterator.next() now skips sockets without __pk metadata.

  4. Filters in getCount() (connection.ts:304-312) - Only counts PartyServer-managed sockets.

  5. Filters in getConnection() (connection.ts:316-327) - Filters by matching __pk.id instead of relying solely on tags.

  6. Guards in lifecycle handlers (index.ts:429-431, 460-462, 485-487) - webSocketMessage, webSocketClose, and webSocketError now early-return for non-PartyServer sockets.

  7. Adds a test (index.test.ts:152-191) with a Mixed server class (worker.ts:65-94) that demonstrates the scenario.

Code quality:

  • ✅ Tests pass (9/9)
  • ✅ Type checking passes
  • ✅ Linting passes
  • ✅ Formatting correct
  • ✅ Good defensive coding with try/catch around deserialization
  • ✅ Clear, descriptive comments explaining the reasoning

Minor suggestions:

  1. tryGetPartyServerMeta could be simplified - The nested object validation is verbose but correct. Consider using a type guard pattern:

    function hasPartyServerMeta(attachment: unknown): attachment is ConnectionAttachments {
      return attachment !== null 
        && typeof attachment === "object"
        && "__pk" in attachment
        && /* ... */;
    }
  2. Performance consideration - getCount() now iterates all sockets calling deserializeAttachment() on each. For DOs with many connections, this could be slower than before. However, this is likely acceptable since getCount() isn't typically called in hot paths.

  3. Missing changeset - The bot flagged this. If this should trigger a patch release, a changeset should be added.

Verdict

Approve with minor suggestion: The PR correctly solves a real interoperability issue with proper defensive coding and good test coverage. The implementation is sound. The only actionable item is adding a changeset if a version bump is desired.

New%20session%20-%202026-01-28T22%3A42%3A22.460Z
opencode session  |  github run

threepointone and others added 2 commits January 28, 2026 22:44
Refactors test files to ensure event handlers are attached before connections, adds explicit type annotations for WebSocket instances, and improves cleanup logic for server and client resources. These changes enhance test reliability, prevent race conditions, and improve type safety in both browser and Node.js environments.
@threepointone
Copy link
Collaborator

using this PR to sneak in some test fixes

Improves reliability of usePartySocket tests by setting up server connection handlers before rendering hooks and removing unnecessary waits for connection establishment. Also ensures proper cleanup of event listeners after each test.
@threepointone threepointone merged commit 0caf2ad into cloudflare:main Jan 28, 2026
0 of 3 checks passed
@github-actions github-actions bot mentioned this pull request Jan 28, 2026
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.

2 participants