openai / openai/codex

Windows: Node child-process pipe setup returns EPERM/PID 0; inherited streams succeed

Open
#44,838 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

In the Windows Codex desktop app, Node child-process calls fail with EPERM/PID 0 whenever any standard stream is piped. The same executable launches successfully with all standard streams inherited. Direct Git execution also succeeds.

This blocks a local verification workflow that must capture exact command output. The observations isolate the failure to the piped-launch path, but do not identify the failing native Windows call or establish the enforcing component.

Environment

  • Windows 11 Home Single Language, 25H2, build 26200.9445, x64.
  • Active client: OpenAI.Codex desktop MSIX package 26.901.6511.0.
  • Running desktop backend: codex-cli 0.153.4.
  • Separate CLI first on PATH: 0.145.0; an additional npm installation reports @openai/codex 0.144.5. These are not the backend running this desktop session; no causal relationship is established.
  • Bundled Node: v24.19.0, under %USERPROFILE%\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin\node.exe.
  • Git: 2.54.0.windows.1, C:\Program Files\Git\cmd\git.exe.
  • Working directory: an existing local workspace; identifying path omitted.
  • No Node execution flags, NODE_OPTIONS, or enabled Node permission model.

Windows version details were obtained from registry/runtime metadata because CIM access was denied. The legacy registry product label says Windows 10; the reported 25H2/build 26200 identifies Windows 11.

Minimal reproduction

Run this JavaScript using the affected bundled Node executable, from the affected workspace. process.cwd() replaces the private workspace path. The trust setting below is command-scoped; no global Git configuration is changed.

const { spawnSync } = require("node:child_process");

const cwd = process.cwd();
const git = "C:/Program Files/Git/cmd/git.exe";
const args = [
  "--no-optional-locks",
  "-c", `safe.directory=${cwd}`,
  "-C", cwd,
  "--version"
];

for (const stdio of [
  ["inherit", "pipe", "inherit"],
  ["inherit", "inherit", "inherit"]
]) {
  const r = spawnSync(git, args, {
    cwd, stdio, encoding: "utf8", timeout: 10000
  });
  console.log({
    stdio,
    status: r.status,
    pid: r.pid,
    error: r.error?.code,
    errno: r.error?.errno,
    stdout: r.stdout
  });
}

The readable version-string probe uses UTF-8 decoding. The blocked verification workflow separately requires raw-byte capture. The sanitized reproduction has not been rerun after substituting the private workspace path.

Previously observed comparisons

All comparisons used the same working directory and unchanged environment.

Invocation Result
Direct Git --version Exit 0
Node → Git, default pipes, bare executable name EPERM, PID 0
Same, absolute Git executable EPERM, PID 0
Node → Git, all streams inherited Exit 0, version printed
Node → Git, only stdin piped EPERM, PID 0
Node → Git, only stdout piped EPERM, PID 0
Node → Git, only stderr piped EPERM, PID 0
Node → itself, default pipes / inherited streams EPERM / exit 0

For the failed piped invocation: error EPERM, errno -4048, PID 0, status null.

The comparison matrix was not repeated during the version-only follow-up.

Expected behavior

A supported, permitted child-process invocation should capture stdout successfully and preserve exact stdout bytes, separate stderr diagnostics, exit status, and launch/timeout error detection, or provide a diagnostic identifying the relevant restriction and supported recovery path. Inherited output alone does not satisfy this workflow.

Diagnostics and limitations

  • No matching events appeared in the inspected 30-minute window in AppLocker EXE/DLL, Code Integrity Operational, Defender Operational, or Security events 4656/4663/4688. This does not exclude an unlogged restriction.
  • Version-only CLI queries additionally emitted access-denied warnings concerning temporary alias creation and stale temporary-directory cleanup. Their relationship to the pipe failure is unknown.
  • No native failure trace has been collected. The underlying cause is not established as managed access enforcement, endpoint protection, or a Node/libuv–Windows interaction.
  • No repository files, configuration, protections, ownership settings, or global Git trust settings were changed during this diagnostic follow-up. No tracing software was installed.
  • Exact timestamps, account identifiers, project names/paths, repository identities, and full logs are intentionally omitted from this public report.

Please identify the failing native Windows call, affected object/pipe, native error, and any enforcing component. Please provide a supported correction preserving existing protections, or a documented permitted equivalent preserving output bytes, diagnostics, and exit/error status.

Related report

  • #35070 reports Windows Node child-process EPERM failures. This report adds an isolated piped-versus-inherited standard-stream comparison on desktop backend 0.153.4. A shared root cause or exact duplicate is not asserted.

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 rerunning the supplied JavaScript minimal reproduction with the bundled Node v24.19.0 and compare piped versus inherited stdio. No repository files or tests are named; completion requires identifying the failing native Windows call, affected pipe or object, native error, and a supported correction or documented permitted equivalent that preserves output, diagnostics, and status.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
devtools, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.