Websocket connection issues on cloudflare workers with @rivetkit/core@0.9.0
I recently used actor-core@0.8.0 to build a game server but had issues with actor-actor communication which stalled deployment.
Since the release of @rivetkit/core@0.9.0, I've migrated the game server to the new API and verified that actor-actor communication works fine. I proxied an RPC request from one actor to another to verify this.
The issue now is websocket connections don't work anymore. I've looked through the and still can't figure out what is causing the issue.
I also cloned the repo to run the cloudflare examples locally, same thing.
On the client I get the below log.
msg="socket closed" code=1002 reason="Mismatch client protocol" wasClean=true
On the server I get:
level=WARN msg="websocket closed" code=1006 reason="WebSocket disconnected without sending Close frame." wasClean=false
Below are the details of the closevent from https://github.com/rivet-gg/rivetkit/blob/feeaadcf1a2de5c271d16022cb8fd74ff6c31ad1/packages/core/src/actor/router-endpoints.ts#L160
I'm not sure what is causing the issues and any pointers will be really helpful.
PS: I've also tried SSE and it doesn't receive any broadcast from the actors.GitHub
rivetkit/packages/core/src/actor/router-endpoints.ts at feeaadcf1a2...
π Stateful Serverless That Runs Anywhere. The easiest way to build stateful, AI agent, collaborative, or local-first applications. Deploy to Rivet, Cloudflare, Bun, Node.js, and more. - rivet-gg/ri...
35 Replies
I've also explored https://github.com/rivet-gg/rivetkit/blob/314843828b8be1e51d9dd52b5c84b4af4abc533d/packages/platforms/cloudflare-workers/src/manager-driver.ts#L94 and all hacks related to cloudflare and still been unable to get it to work.
I use node 24 and pnpm 10.
GitHub
rivetkit/packages/platforms/cloudflare-workers/src/manager-driver.t...
π§° Lightweight libraries for backends. Install one package, scale to production. Just a library, no SaaS. - rivet-gg/rivetkit
hey! it's late here, i'll give this a look in the morning.
this should be covered by our test cases, but i'll double check it's doing exactly what you described.
can you share a code snippet of the relevant parts of the code?
haha you really went deep
haha yes, I've spent about 3 weeks building a game server and found rivet and had it done in about a day. This is my new favourite library π .
Yes, I just modified the cloudflare-workers example to publish the state when increment is called.
aye that's awesome!
where did you find us?
let me give this a go in the morning π«‘
Great. Thanks. I'll keep an eye out.
Open alternative https://openalternative.co/rivet. The quickstart took about 5 minutes to get through and deploy. It is an amazing framework that has already highlighted multiple use cases for the platform I'm working on.
didn't get to the bottom of this today, currently top of the todo list
Great thanks for looking into it. Any pointers on what I should look at in the codebase or a design doc that can guide me?
Because it works on actor-core and just fails with actor-actor comms.
thereβs a file called something like βhttp client driver.β iβm afk so i canβt find it quickly. we migrated to pnpm right before we launched which broke the cf test suite, so itβs unfortunately probably not the quickest thing to get back up.
if you just need to test locally β id recommend just using nodejs for a minute while i get this fixed up.
Thanks, I'll look through the files and follow the failed tests. Unfortunately, I need to test on cloudflare
looking now
π
https://github.com/rivet-gg/rivetkit/pull/1060#issuecomment-3029735076 fix is live, will cut release later today
thanks for reporting!
if you're able to keep a running list of any pain points, annoyances, or feature requests as you work with rivetkit β it'd be incredibly helpful
Thanks for the quick fix. I'll look through the PR to see what caused the issue.
Definitely, I'll share what I find.
A bit strange. I just had a look at your PR. I applied a patch to fix the missing
return when I followed the logs which fixed the below error.
Before the patch, these were the error logs:
Then after the patch, the error changed and the logs from the connection error became,
So the websocket connection still fails.
Did you run the client with a websocket connection?
Another error shows up when you try to connect from the client.i ran my demo with a ws connection, let me try your code
that's odd, it works for me with
https://pkg.pr.new/rivet-gg/rivetkit/@rivetkit/actor@1060
can you send your index.ts?
import { createServerHandler } from "@rivetkit/cloudflare-workers";
import { registry } from "./registry";
const { handler, ActorHandler } = createServerHandler(registry);
export { handler as default, ActorHandler };
I didn't make any changes to index.ts.
roger, i'll try with a fresh project in a moment and send over a zip if it works
I just pulled your branch and added the broadcast. I'm still getting same error π₯²

oh boy, this is a spicy one
are you on windows by chance?
+ what package manager & what command are you using to run the server? curious if your machine is using a diff version of wrangler.
i can reproduce part of the error after upgrading wrangler. give me a minute.
I'm on a mac m2
There's no local version of wrangler installed so the npm version is what is being used.
Package manager pnpm v10, node v24
this is mad haha
i'm on linux, let me try running this locally on my mac. i'll push another branch in a second if you'd be kind enough to test again
ah i see the issue here β try this client:
working on updating docs & logging a warning to prevent this error: https://github.com/rivet-gg/rivetkit/issues/1061
GitHub
chore: log warning if mixing using handler & connection Β· Issue #1...
Mixing using the actor handle and actor connection can cause some unexpected behaviors in terms of race conditions. Update the actor client & handle: Log warning if calling stateless rpcs on a ...
It does work from the browser now but still failing with the sample you sent.
Can you send the full logs of the error? The screenshot above is clipped.
Sure, I'll rerun it and send it over today.

import { createClient } from "@rivetkit/actor/client";
import type { registry } from "../src/registry";
// Create RivetKit client
const client = createClient<typeof registry>(
process.env.RIVETKIT_ENDPOINT ?? "http://localhost:8787",
);
async function main() {
console.log("π Cloudflare Workers Client Demo");
try {
// Create counter instance
const counter = client.counter.getOrCreate("demo").connect();
console.log("connect");
counter.on("increment", console.log);
counter.on("foo", (x) => console.log("=== output ===", x));
// await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for connection
// Increment counter
console.log("Incrementing counter 'demo'...");
const result1 = await counter.increment(1);
console.log("New count:", result1);
// Increment again with larger value
console.log("Incrementing counter 'demo' by 5...");
const result2 = await counter.increment(5);
console.log("New count:", result2);
// Create another counter
const counter2 = client.counter.getOrCreate("another");
console.log("Incrementing counter 'another' by 10...");
const result3 = await counter2.increment(10);
console.log("New count:", result3);
console.log("β
Demo completed!");
setTimeout(() => {}, 1000);
} catch (error) {
console.error("β Error:", error);
process.exit(1);
}
}
main().catch(console.error);
// client code
any idea where "user" is coming from? it's not in your code

I have a full setup in react. The frontend was still running and tried to connect to the server. DO you think that is causing any issues?
ah gotcha. i donβt think so, i was just confused by the logs
just noticed youβre using bun to run the test script. bun has a different websocket implementation than node, iβll see if i can reproduce it with that later today.
Ok, I'll spin it up with node.
That probably explains why it works in the browser.
thanks for taking the time to help get this fixed β let me know if you run in to any more issues or have feedback!