Skip to content

Fix Xdebug not starting on a normal page load on the native PHP runtime#4086

Open
juanmaguitar wants to merge 4 commits into
trunkfrom
fix-xdebug-start-with-request-native
Open

Fix Xdebug not starting on a normal page load on the native PHP runtime#4086
juanmaguitar wants to merge 4 commits into
trunkfrom
fix-xdebug-start-with-request-native

Conversation

@juanmaguitar

@juanmaguitar juanmaguitar commented Jul 6, 2026

Copy link
Copy Markdown

Related issues

Fixes #4087

Proposed Changes

Enabling Xdebug on a site is already an explicit, per-site, mutually-exclusive opt-in — only one site can have it on at a time. The docs (https://developer.wordpress.com/docs/developer-tools/studio/xdebug/) say that once it's on, you just "navigate to your site in the browser to trigger the breakpoints." That's true on the sandbox (Playground/PHP-WASM) runtime, but not on the native PHP runtime (default since Studio 1.13): a normal reload does nothing, and you need ?XDEBUG_TRIGGER=1 or the Xdebug Helper browser extension for the debugger to actually break.

Root cause: on native, Studio sets xdebug.mode=debug but never sets xdebug.start_with_request, so Xdebug falls back to its own default, which resolves to trigger for mode=debug (https://xdebug.org/docs/all_settings#start_with_request). The sandbox runtime doesn't hit this because it goes through @php-wasm/xdebug-bridge, a different code path that isn't gated on the trigger. It looks like start_with_request was simply never carried over when native became the default runtime.

This PR sets xdebug.start_with_request=yes whenever Xdebug is enabled on the native runtime, restoring "navigate to your site → breakpoints fire" for the one site that has it explicitly turned on. Trade-off: Xdebug will now attempt a connection on every request to that site (AJAX, heartbeat, cron), not just triggered ones — same as the sandbox runtime already does today, and scoped to a single opt-in site.

Was leaving start_with_request at its default intentional, or a side effect of the native migration? I think we should keep the behavior documented in the docs and avoid extra steps for the final user to enable X-Debug on a site.

Testing Instructions

Follow the setup steps at https://developer.wordpress.com/docs/developer-tools/studio/xdebug/ (IDE config, etc.), then:

  • Ensure WordPress Studio runs v1.13.0 or later (native PHP runtime)
  • Create a new site and enable Xdebug for it
  • Start listening for Xdebug in your IDE (e.g. VS Code "Listen for Xdebug") and set a breakpoint
  • Reload the site in the browser — no need for ?XDEBUG_TRIGGER or the Xdebug Helper extension
  • Before this fix: the breakpoint never hits on a plain reload. It only hits if you add ?XDEBUG_TRIGGER=1 to the URL, or use the Xdebug Helper browser extension to turn debugging on for the request — because Xdebug's start_with_request setting defaults to trigger, so it only starts a session when explicitly triggered (see https://xdebug.org/docs/all_settings#start_with_request)
  • After this fix: the breakpoint hits on the plain reload, no trigger needed, as the docs describe

Also covered by a new unit test: apps/cli/lib/native-php/tests/config.test.ts.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

How AI was used in this PR

Investigated with Claude Code: traced the regression to apps/cli/lib/native-php/config.ts, confirmed it against a live native-runtime site (Xdebug's DBGp <init> handshake only fired with ?XDEBUG_TRIGGER=1, never on a plain reload), wrote the one-line fix + a unit test, and verified end-to-end (lint, typecheck, unit test, and a live re-test confirming the handshake now fires on a plain request) before opening this PR. All findings and the fix were reviewed by me before submitting.

Native PHP never set xdebug.start_with_request, so Xdebug fell back to its
own default (trigger), requiring XDEBUG_TRIGGER/XDEBUG_SESSION on every
request. The sandbox runtime doesn't have this restriction, and the docs
promise "navigate to your site to trigger the breakpoints" — so this was a
silent regression for the one site a user explicitly enables Xdebug on.
@wpmobilebot

wpmobilebot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing dfc0d37 vs trunk

app-size

Metric trunk dfc0d37 Diff Change
App Size (Mac) 1411.92 MB 1411.92 MB +0.00 MB ⚪ 0.0%

site-editor

Metric trunk dfc0d37 Diff Change
load 747 ms 734 ms 13 ms ⚪ 0.0%

site-startup

Metric trunk dfc0d37 Diff Change
siteCreation 6465 ms 6485 ms +20 ms ⚪ 0.0%
siteStartup 2390 ms 2382 ms 8 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

@juanmaguitar juanmaguitar requested review from bcotrim, sejas and wojtekn July 7, 2026 08:53

@wojtekn wojtekn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code change looks reasonable. Good catch, thanks for the fix.

// https://xdebug.org/docs/all_settings#start_with_request. Studio's
// Xdebug is already an explicit, one-site-at-a-time opt-in, so once
// it's on we want every request on that site to start a debug
// session — matching the sandbox (php-wasm) runtime

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this comment more concise?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Xdebug doesn't start on a normal page load, contrary to the docs

3 participants