pingdotgg / pingdotgg/t3code

[Bug]: macOS agent terminals fail with 'posix_spawnp failed' - node-pty spawn-helper ships without exec bit

Open
#4,924 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

What happened

After npm i -g t3 on macOS (arm64), the server starts fine but every agent terminal fails to spawn:

node_modules/node-pty/lib/unixTerminal.js:92
        var term = pty.fork(file, args, parsedEnv, cwd, ...);
                       ^
Error: posix_spawnp failed.
    at new UnixTerminal (node-pty/lib/unixTerminal.js:92:24)
    at Object.spawn (node-pty/lib/index.js:30:12)
Root cause

Not a missing prebuild — prebuilds/darwin-arm64/pty.node is present and the native module loads fine. The problem is the helper binary next to it:

$ find $(npm root -g)/t3/node_modules/node-pty/prebuilds -name spawn-helper -exec stat -f "%Sp %N" {} \;
-rw-r--r--  .../prebuilds/darwin-arm64/spawn-helper
-rw-r--r--  .../prebuilds/darwin-x64/spawn-helper

spawn-helper has no execute bit, so posix_spawnp on it fails.

This originates in the published node-pty tarball, not in npm's extraction:

$ npm pack node-pty@1.1.0 && tar tvf node-pty-1.1.0.tgz | grep spawn-helper
-rw-r--r--  0 0 0  50480  package/prebuilds/darwin-arm64/spawn-helper
-rw-r--r--  0 0 0   9248  package/prebuilds/darwin-x64/spawn-helper

And node-pty's scripts/post-install.js only operates on build/Release, never on prebuilds/, so nothing ever restores the bit.

Important: --allow-scripts does not fix this

There is a known, separate node-pty issue on Linux where npm's script gating blocks the native build (NodePtyModuleLoadError), worked around with npm i -g --allow-scripts=node-pty,msgpackr-extract t3@nightly. That workaround does not help here. Verified into a throwaway prefix:

$ npm install -g t3@0.0.31 --prefix /tmp/x --allow-scripts=node-pty,msgpackr-extract
added 197 packages in 4s
$ find /tmp/x -name spawn-helper -exec stat -f "%Sp %N" {} \;
-rw-r--r--  .../darwin-x64/spawn-helper
-rw-r--r--  .../darwin-arm64/spawn-helper

Still non-executable. These are two distinct bugs with a similar smell, which makes this one easy to misdiagnose as the Linux one (I did exactly that at first). Closed issues #2621 and #204 are the missing-prebuild variant, not this.

Workaround
find $(npm root -g)/t3/node_modules/node-pty/prebuilds -name spawn-helper -exec chmod +x {} \;

Verified working afterwards with a real spawn (pty.spawn('/bin/echo', ['pty-ok']) returns pty-ok). Note this must be repeated after every npm i -g t3, since a fresh extraction resets the mode.

Suggested fix

Ultimately this belongs upstream in microsoft/node-pty (ship prebuilds/*/spawn-helper with mode 0755, or extend post-install.js to chmod the prebuilds dir). But since T3 Code is where it surfaces and the CLI is unusable without it, a defensive chmod on the resolved spawn-helper path at server startup would make installs work regardless of upstream timing.

Happy to open the upstream node-pty issue too if useful.

Reproduction (clean room)
mkdir /tmp/repro && cd /tmp/repro && npm init -y
npm install t3@0.0.31
find node_modules/node-pty/prebuilds -name spawn-helper -exec stat -f "%Sp %N" {} \;
# -> -rw-r--r--
Environment
  • macOS 26.5.2, arm64 (Apple Silicon)
  • Node v24.18.0, npm 11.16.0
  • t3 0.0.31 and 0.0.32-nightly.20260730.953 — both affected
  • node-pty 1.1.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the clean-room npm install and inspecting node_modules/node-pty/prebuilds/*/spawn-helper, then read node-pty's scripts/post-install.js and trace T3's server startup path. Verify the executable mode and a real pty.spawn call on macOS arm64; the issue is resolved when a fresh install can spawn an agent terminal without the manual chmod workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js
Domain
backend, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.