Surface PHP errors when a site fails to start - #3813
Merged
Conversation
Collaborator
📊 Performance Test ResultsComparing 9c21596 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
bcotrim
marked this pull request as draft
June 12, 2026 15:26
bcotrim
marked this pull request as ready for review
June 15, 2026 14:33
epeicher
approved these changes
Jun 16, 2026
epeicher
left a comment
Contributor
There was a problem hiding this comment.
Thanks @bcotrim, this is a great improvement for debugging and identifying errors! I have tested it, and I can confirm that the changes surface the error and they are logged on either server-error.log or debug.log depending on the setting. I have also confirmed that the UI also returns the error as expected and the error is logged in the Studio log file too.
Changes LGTM!
| Before | After | When enabling debug.log |
|---|---|---|
![]() |
![]() |
![]() |
gcsecsey
added a commit
that referenced
this pull request
Jul 31, 2026
## Related issues - Related to STU-1370 - Ships the upstream fix WordPress/wordpress-playground#3478, released in Playground v3.1.45 ## How AI was used in this PR I used Claude to trace STU-1370 to the upstream `runCLI()` `process.exit()` behavior, confirm the fix shipped in Playground 3.1.45, bump the dependencies, and regenerate the lockfile. I reviewed the diff and verified single-copy resolution of the Playground and PHP-WASM packages myself. Claude also diagnosed and fixed the Windows-only CLI E2E failure the bump surfaced (see below), reproducing it locally on Windows. ## Proposed Changes Studio runs each site's Playground server in a child process that imports `runCLI()` from `@wp-playground/cli`. When a site hit a PHP error during startup, `runCLI()` called `process.exit(1)` before the error could propagate, which killed the child process, so Studio's error handling never ran and the real error was lost. The upstream fix (WordPress/wordpress-playground#3478, in 3.1.45) removes `process.exit()` from the Playground CLI's library APIs, so `runCLI()` now throws instead of exiting. This PR: - Bumps Playground and PHP-WASM to 3.1.45 to pick up that fix - This is the prerequisite that lets Studio catch PHP-error start failures at all. On its own it makes the failure report the real PHP error (via the existing #3813 handling) instead of tearing the child process down. The user-facing STU-1370 behavior (the site starting and serving the error page) is a follow-up PR that depends on this bump. - Lockfile note: alongside the version bumps, npm deduped `fast-xml-parser` (a nested duplicate collapsed into a single top-level copy, within existing ranges) and added `zstddec`, a new dependency of `@wp-playground/wordpress@3.1.45`. - Windows import fix: on Windows, importing a backup into a running site failed to restart the server with `Error connecting to the SQLite database`. `wp sqlite import` leaves the imported database in WAL journal mode, and 3.1.45 boots the site through the WASM SQLite driver, which cannot reopen a WAL-mode database on Windows (WAL needs shared memory the WASM filesystem can't provide there). After importing, Studio now converts the database back to rollback (DELETE) journal mode — using Node's native `node:sqlite`, since PHP-WASM itself can't touch the WAL database — so Playground can reliably reopen it. ## Testing Instructions Because 3.1.45 is still inside the npm cooldown window, install locally with the cooldown bypassed. A plain `npm install` works from 2026-07-18 onward. - Check out this branch and run `npm install --min-release-age=0` - Confirm the lockfile resolves a single 3.1.45 copy of every `@wp-playground/*` / `@php-wasm/*` package, with no nested duplicates - `npm run typecheck` passes - `npm run cli:build && node apps/cli/dist/cli/main.mjs --version` builds and runs - Smoke test: create and start a local site, confirm it loads and runs normally — i.e. no regression from the runtime bump - On Windows, confirm the import fix: `npm run cli:build` then `npm test -- apps/cli/commands/tests/import.e2e.test.ts --tagsFilter='e2e' --no-file-parallelism -t 'imports a backup into a running site'` ## Pre-merge Checklist - [ ] Have you checked for TypeScript, React or other console errors? - [ ] Confirm the merge date is on or after 2026-07-18 (around 04:13 UTC) so CI can install 3.1.45 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Related issues
How AI was used in this PR
Built with Claude Code: it traced the error-reporting flow, reproduced the failure against plain Playground CLI to isolate root causes, implemented the fix, and verified it end-to-end. All code human-reviewed; the findings were verified with live runs, not just code reading.
Proposed Changes
When a site fails to start (e.g. an active plugin or theme fatals during WordPress load), Studio only showed
WordPress server process exited unexpectedly— the actual PHP error was recorded nowhere, so there was no way to diagnose it. (WordPress'sWP_DEBUG_LOGis disabled too early in boot to catch a boot fatal, and Playground CLI swallows the error.)Now Studio captures PHP errors during start via a small mu-plugin and appends them (warning + fatal + stack trace) to the failure message — in the CLI and the desktop app alike. The capture writes to the site's
debug.logwhen the debug-log setting is on, or an internalstudio-error.logwhen off (cleared each start, excluded from exports/sync). It defers to any logging the user already configured, so a customWP_DEBUG_LOGis left untouched.Out of scope: fatals in the user's own
wp-content/mu-plugins/orwp-config.phpfire before the capture loads. The--verboseflag from the issue title can build on this later.Testing Instructions
Create a throwaway site and make it fail to boot — easiest in the desktop app:
require_once 'nope.php';towp-content/themes/<active-theme>/functions.php.WordPress server process exited unexpectedly).Or via the CLI (build first with
npm run cli:build):Expected:
Also verify:
studio-error.logis left behind.debug.loginstead, and runtime errors keep going there.Cleanup:
node apps/cli/dist/cli/main.mjs site delete --path ~/Studio/stu1757-demo(or delete it from the app).Pre-merge Checklist
🤖 Generated with Claude Code