Skip to content

Building a Gutenberg site never finishes and spawns processes without bound #275

Description

@juanmaguitar

Description

Building a Gutenberg site never finishes. The wizard stays on "Run build" forever, and behind it the app spawns processes without bound — over 1,300 in a few minutes on a machine that then becomes unusable. The build makes no progress at any point; nothing is ever written to build/.

The same checkout builds normally outside the app: run npm run build in it with a system Node and it completes, so this is not a Gutenberg problem. It is specific to how the app runs npm scripts.

Core sites are unaffected — their build is Grunt, which never reaches the code path below.

Step-by-step reproduction instructions

  1. Create a site and choose Gutenberg as the contribution target.
  2. Let the wizard clone the repository and install dependencies.
  3. Start the Run build step.
  4. Watch the process list (ps -A | grep -c concurrently). It grows steadily and never stops; the step never completes.

Screenshots, screen recording, or logs

The last output the step ever prints is Gutenberg's own build banner:

15:47:49.602 (build#85e8)   › 📦 Building workspaces...

Every spawned process has the same shape, repeated to whatever depth the machine allows:

bash /var/folders/.../electron-node-shims-<pid>/node .../node_modules/.bin/concurrently
  .../Electron.app/Contents/MacOS/Electron .../node_modules/.bin/concurrently
    bash /var/folders/.../electron-node-shims-<pid>/node .../node_modules/.bin/concurrently
      ...

Operating system

macOS

App version

1.0.0-beta.1 (development build, on the branch adding Gutenberg support)

Technical notes

Root cause is the interaction between the app's Node shims and any dependency whose bin has a #!/usr/bin/env node shebang and in turn spawns npm.

  • To give spawned npm scripts a node with zero prerequisites installed, the app writes shims into a temp directory and puts them on PATH (src/main.js:139). That node is not Node: it is ELECTRON_RUN_AS_NODE=1 <Electron binary>. npm/npx shims are written the same way, and src/script-runner.js:33-35 additionally rewrites npm_execpath and npm_node_execpath to point at Electron.
  • Gutenberg's build reaches npm run --if-present --workspaces build (tools/build-scripts/build.mjs:125), which runs the build script of every workspace.
  • One of those workspaces, packages/block-serialization-spec-parser, has "build": "concurrently \"npm run build:js\" \"npm run build:php\"".
  • node_modules/.bin/concurrently starts with #!/usr/bin/env node, so under the shims each invocation launches a full Electron process, which re-enters npm, which re-enters concurrently. There is nothing to terminate the recursion.

Measured both ways on the same checkout: that workspace's build finishes in about three seconds with two processes under a system Node, and recurses without bound under the app's shims.

Not yet established: why the recursion lands back on concurrently rather than costing one Electron process per bin. The rewritten npm environment re-running build instead of the requested build:js is the likely explanation but is still unconfirmed — instrumenting PATH does not work here, because npm imposes its own shim directory on the scripts it runs.

Worth checking whether the fix should be narrow (make the shims safe to re-enter) or broad (stop putting a fake node on PATH when a real one is available), since the shims are on every spawn path, not just this one.

This blocks the Gutenberg contribution target: a Gutenberg site cannot be built from the app at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: build-installnpm install, builds, the dev serverbugSomething isn't workinggutenberg-contributionsSupport Gutenberg as a contribution target (#251)next-validationAffects the next real-user validation round

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions