agent timed out waiting for durable object websocket: connect failed in dev
Fixes a local dev websocket connection to a Durable Object that fails or times out. The skill makes the agent wait for wrangler dev's ready line, build the URL from the printed address with the ws scheme, confirm the worker handles the upgrade handshake, and read the rejection status to tell a bad route from bad upgrade handling.
TL;DR: Connect only after wrangler dev prints its ready line, using the exact address it prints with the ws scheme. Most dev websocket failures are connecting too early, using the wrong URL, or a worker that never handles the upgrade handshake.
agent timed out waiting for durable object websocket: connect failed in devSteps
Wait for
wrangler devto print its ready line before attempting any connection. Expected: the ready message appears in the dev server output.Build the websocket URL from the printed address, swapping the scheme to ws and using the worker route that performs the upgrade. Expected: a URL that matches the live dev server and the upgrade route exactly.
Confirm the worker handles the upgrade: it must check the Upgrade header for "websocket" and return a 101 response paired with the socket. Expected: the upgrade branch exists in the worker code.
Connect and expect 101 Switching Protocols. Expected: the socket opens. On failure, read the HTTP status in the rejection: 404 means the route is wrong, 400/500 means the upgrade handling is wrong.
Set the connect timeout above local cold-start time and allow one retry. Expected: no false timeouts on a slow first start.
Use this when
- A websocket to a Durable Object fails to connect in
wrangler dev - The agent times out waiting for the socket to open locally
- The same websocket code works when deployed but not in dev
Not for this skill when
- The websocket fails in production (check routes and the deployed upgrade handling instead)
- The worker never intends to upgrade the connection (not a websocket problem)
- The dev server itself fails to start (fix startup first)
Variant phrasings
- durable object websocket connection refused in local dev
- wrangler dev websocket 404
- websocket upgrade failed in miniflare
- DO stub websocket connect timeout local
Why it happens
In local dev the websocket server only exists once workerd has finished booting the worker, so early connects hit nothing. Agents also commonly reuse the production wss URL against the dev server, or connect to a route the worker does not upgrade. The rejection status distinguishes these cases, but only if the agent reads it instead of treating every failure as a timeout.
Edge cases
- Some dev setups need the connection to go through the worker's fetch handler first (subrequest to the DO stub); connecting straight at the stub bypasses routing.
- Hibernation APIs change which side holds the socket; confirm the pattern matches the local workerd version.
- Browser clients enforce mixed-content rules; test the dev websocket from a ws-capable client, not an https page.
- If the worker upgrades conditionally on a path prefix, the connect URL must include that prefix exactly.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst7sWo2MebfgGGigtmDwjaw