Automattic / Automattic/studio

playground-cli: setAdminCredentials deadlocks in-process and default worker count triggers file-lock deadlock

Open
#3,628 0 comments 0 reactions 0 assignees View on GitHub
Bug YOLO
Dominant language
TypeScript
Stars
517
Forks
95
Avg merge
1d 22h
Merged PRs (30d)
162

Description

Hi! Filing two small bugs we've been carrying a downstream patch for since the May 2026 `wp-studio@1.7→1.8` line. Both still reproduce against `wp-studio@1.9.0` and `1.10.0-beta4`. Happy to send PRs if either looks right to you in principle.

We're using the playground runtime (not native-PHP) on a 4-vCPU Linux runner (Blacksmith).

---

### 1\. `setAdminCredentials` in-process call deadlocks during install

`apps/cli/src/playground-server-child.ts → setAdminCredentials` posts to `/?studio-admin-api` via `server.playground.request(...)`. That's an in-process request that blocks while the PHP workers are tied up applying the Blueprint. The result is that admin-credentials setup never returns, then `startServer` times out under the daemon's heartbeat watchdog. The CLI hangs at *"Starting WordPress server and applying Blueprint…"*.

The v1.10.0-beta refactor changed the shape of the helper but still routes through `server.playground.request(...)`, so the deadlock survives:

```ts
// v1.10.0-beta4
async function setAdminCredentials(server2, config) {
await requestSetAdminCredentials(config, async (request) => {
await server2.playground.request(escapeRequestForPlayground(request));
});
}
```

**Workaround we ship downstream** ([patch]()): hit the same `/?studio-admin-api` endpoint over TCP `fetch` instead, with a \~60s retry to absorb the window before the MU plugin's `plugins_loaded` callback is ready (otherwise the endpoint returns 400). This consistently completes in a couple seconds.

**Suggested upstream fix:** swap the in-process request for a TCP `fetch` against `server.serverUrl` (or expose a hook that lets the embedder do so), with a short retry to handle the install-not-ready race.

---

### 2\. Playground default `workers` triggers the upstream file-lock deadlock warning

`apps/cli/src/playground-server-child.ts → getBaseRunCLIArgs` doesn't pass a `workers` option to `runCLI`. `@wp-playground/cli` then defaults to `min(6, cpus-1)` — which is 3 on a 4-vCPU runner. The playground-cli itself prints:

> Running fewer than 6 workers may increase the likelihood of deadlock due to workers blocking on file locks.

And we hit exactly that during `setAdminCredentials` even after fixing bug Automattic/studio#1 above. Pinning `workers: 6` in the runCLI args makes it reliable.

**Workaround:** the second hunk in our patch passes `workers: 6` explicitly.

**Suggested upstream fix:** either pass `workers: 6` (the playground-cli's own recommended minimum) by default from studio, or bump the default in `@wp-playground/cli` so its own warning isn't routinely tripped.

---

### Context / version

| | Version |
| -- | -- |
| `wp-studio` | `1.9.0` (reproduces on `1.10.0-beta4` too) |
| `@wp-playground/cli` | transitively pulled at `3.1.21` |
| Node | `24.15.0` (with `--experimental-wasm-jspi`) |
| OS / CPUs | Linux, 4 vCPU |

For what it's worth, the third bug we'd been patching — `startServer` returning `undefined`, causing the IPC ack to be dropped — was already fixed by [marking `result` as `optional` in `wordpress-server-ipc.ts`]() in `1.8.2`. Thank you for that one! 🙏

### References

* Our downstream PR with full analysis: [https://github.com/phillypublishing/ems/pull/436]()
* Our tracking issue: [https://github.com/phillypublishing/ems/issues/438]()
* Current downstream patch: [https://github.com/phillypublishing/ems/blob/chore/wp-studio-1.9.0/patches/wp-studio%401.9.0.patch]()

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.