Skip to content

CLI worker threads swallow fatal PHP-WASM rejections and leave requests pending #4160

Description

@chubes4

Problem

The published @wp-playground/cli@3.1.46 blueprint v1/v2 worker entrypoints install this handler:

process.on("unhandledRejection", (reason) => {
  logger.error("Unhandled rejection:", reason);
});

When PHP-WASM rejects fatally, the handler logs and keeps the poisoned worker alive. The parent request remains pending indefinitely rather than receiving a worker error/exit. Callers with an outer timeout only fail after that full timeout.

Reproduction evidence

WP Codebox PHPUnit execution against an external MySQL service consistently emits:

Unhandled rejection: RuntimeError: null function or function signature mismatch
    at php.wasm.mysqlnd_stream_array_from_fd_set
    at php.wasm.zif_mysqli_poll
Error [RuntimeError]: unreachable
    at php.wasm.wasm_sapi_handle_request

The pending playground.run() request then times out after 1,500,002 ms. This reproduced three times with distinct workers/runtimes.

Owning tracker: Automattic/wp-codebox#2010
Latest consumer job: https://github.com/Extra-Chill/data-machine/actions/runs/30094573746/job/89540835546
Observation artifact: https://github.com/Extra-Chill/data-machine/actions/runs/30094573746/artifacts/8604275717

Expected behavior

A fatal unhandled rejection in a CLI worker should terminalize that worker and propagate a nonzero exit/error to the parent request promptly. Logging may be retained, but the worker must not continue serving after the PHP runtime is unreachable.

Verified candidate

Rethrowing after logging in both ESM worker entrypoints causes Node to emit the worker error event and exit nonzero. A process-boundary regression that launches the real v1/v2 worker files, triggers a WASM rejection inside each worker after initialization, and requires prompt nonzero exit passes. WP Codebox is carrying this as a temporary patch-package overlay until the published CLI includes equivalent behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions