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
- Create a site and choose Gutenberg as the contribution target.
- Let the wizard clone the repository and install dependencies.
- Start the Run build step.
- 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.
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 buildin 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
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:
Every spawned process has the same shape, repeated to whatever depth the machine allows:
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 nodeshebang and in turn spawns npm.nodewith zero prerequisites installed, the app writes shims into a temp directory and puts them onPATH(src/main.js:139). Thatnodeis not Node: it isELECTRON_RUN_AS_NODE=1 <Electron binary>.npm/npxshims are written the same way, andsrc/script-runner.js:33-35additionally rewritesnpm_execpathandnpm_node_execpathto point at Electron.npm run --if-present --workspaces build(tools/build-scripts/build.mjs:125), which runs thebuildscript of every workspace.packages/block-serialization-spec-parser, has"build": "concurrently \"npm run build:js\" \"npm run build:php\"".node_modules/.bin/concurrentlystarts with#!/usr/bin/env node, so under the shims each invocation launches a full Electron process, which re-enters npm, which re-entersconcurrently. There is nothing to terminate the recursion.Measured both ways on the same checkout: that workspace's
buildfinishes 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
concurrentlyrather than costing one Electron process per bin. The rewritten npm environment re-runningbuildinstead of the requestedbuild:jsis the likely explanation but is still unconfirmed — instrumentingPATHdoes 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
nodeonPATHwhen 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.