TL;DR: Something is already listening on 8787, usually a previous wrangler dev that did not exit. Find the process and stop it, or start this session on another port with the port flag. The error is about the port, never about your code.

```text
wrangler dev: "Port 8787 is already in use"
```

1. Confirm what holds the port. Run:
   ```bash
   lsof -i :8787
   ```
   Expected: one or more lines showing the process name and PID. A node or workerd process means a stale wrangler dev.

2. If it is a stale wrangler dev you no longer need, stop it:
   ```bash
   kill PID
   ```
   using the PID from step 1. If it ignores the kill, use kill -9 on the PID.
   Expected: a repeat of the lsof command shows nothing listening.

3. Start wrangler dev again:
   ```bash
   wrangler dev
   ```
   Expected: the dev server starts and prints the local URL it is listening on.

4. If you need both sessions running, give this one a different port:
   ```bash
   wrangler dev --port 8788
   ```
   Expected: the dev server starts on 8788 and prints that URL.

5. If the port is held by something you do not recognize, check for duplicate terminal tabs or an editor extension that auto-starts wrangler.
   Expected: you find the launcher and can stop it from the source instead of killing it every time.

## Use this when
- wrangler dev exits immediately with the port-in-use message
- a previous dev session was closed by killing the terminal instead of quitting cleanly
- two projects need local dev servers at the same time
- CI or a script starts wrangler dev and a previous run is still alive

## Not for this skill when
- wrangler dev starts but the worker code fails (that is a code or binding error)
- the error is about the inspector port rather than 8787
- the dev server starts but requests hang (that is a worker logic problem)
- you cannot bind any port at all (that is a machine-level networking problem)

## Variant phrasings
- wrangler dev port already in use
- "Port 8787 is already in use" cloudflare
- cannot start wrangler dev port taken
- workerd port 8787 conflict
- wrangler dev address already in use

## Why it happens
Only one process can listen on a port at a time. wrangler dev binds 8787 for the local worker, and if a previous session is still alive, perhaps orphaned when its terminal was killed, the new session cannot bind it and exits with this message. It looks like a wrangler bug but it is the operating system refusing the second bind.

## Edge cases
- The inspector uses its own port. If you run two dev sessions you may need to set the inspector port too, or let wrangler pick.
- kill -9 on a workerd process can leave the local state directory locked. If dev misbehaves after the kill, remove the .wrangler state directory and start fresh.
- Some editors restart wrangler dev on file save through tasks. That can re-grab the port right after you free it. Check background tasks before assuming the kill failed.
- In containers, the conflicting process may be in another container sharing the network namespace. lsof inside your container will not see it.
- Choosing a fixed alternate port per project in your npm scripts avoids the whole dance when you routinely run two projects.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_V0esapO94vjLSaH_8tyHDQ
