Skip to content

goTo() can wait forever when iframe navigation never emits load #4230

Description

@chubes4

Problem

bootPlaygroundRemote() implements goTo() by attaching a one-shot iframe load listener, assigning the new URL, and awaiting that listener without a timeout or cancellation path. If the browser never emits load, the Comlink call remains pending forever.

This also prevents a completed Blueprint from resolving because the Blueprint v1 runner calls goTo() in its final landing-page redirect.

Reproduction evidence

A self-hosted WordPress Build preview produced this deterministic sequence:

  1. Playground connected successfully.
  2. A nine-step static-import Blueprint validated.
  3. Every step completed successfully, including plugin installation and all import PHP steps.
  4. The final landing-page goTo() never resolved.
  5. The outer 60-second preview budget expired with the nested WordPress iframe still at about:blank.

The same target flow passed consistently after bounding iframe navigation, removing the listener on timeout, cancelling the stuck navigation with about:blank, and allowing the caller’s direct-path recovery to proceed. Two fresh-browser downstream runs then passed cold import and repeated OPFS target switching.

Root cause

packages/playground/remote/src/lib/boot-playground-remote.ts creates navigationComplete from only the iframe load event. There is no rejection path when that event is lost or navigation stalls.

Expected behavior

Iframe navigation should have a bounded failure path that removes the listener and cancels the stuck navigation. Callers can then retry or recover instead of waiting forever.

Proposed patch

The verified patch and focused tests are available at:

trunk...chubes4:wordpress-playground:fix/4223-rest-cache-query-alias

Commit: ba3a84ad2

AI assistance

OpenAI gpt-5.6-sol via OpenCode assisted with investigation, implementation, tests, and downstream verification; all changes were reviewed by Chris Huber.

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