setup-learning.ts fails on Windows with "spawn npx.cmd EINVAL"
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 80/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- nodejs, typescript
Research direction
Start with runCli in server/src/learning/ensure-container.ts (around lines 124-149), where spawn is called without shell on Windows, and trace the entry from scripts/setup-learning.ts. Reproduce on Windows with bun scripts/setup-learning.ts to see the EINVAL, and check that the child.on("error") handler is bypassed. Done when the setup script runs on Windows and the CLI commands succeed, with macOS and Linux behaviour unchanged.
Written by the indexing model from the issue text.
Description
On Windows, bun scripts/setup-learning.ts (Quick start, step 2) stops before doing anything, and prints only this:
PS C:\...\openbot> bun scripts/setup-learning.ts
spawn npx.cmd EINVAL
npx --yes copilotkit@latest login and project select had both succeeded beforehand, from the OpenBot root. Nothing is written to .env, so neither the runtime key nor the openbot Learning container is set up.
Cause
runCli in server/src/learning/ensure-container.ts:124-149 starts the CopilotKit CLI like this:
const child = spawn(
process.platform === "win32" ? "npx.cmd" : "npx",
["--yes", "copilotkit@latest", ...args],
{ cwd: directory, env: cliEnvironment(), stdio: ["ignore", "pipe", "pipe"] },
);
Since the fix for CVE-2024-27980, Node refuses to spawn a .cmd or .bat file without shell: true, and Bun does the same. The refusal is a synchronous EINVAL thrown by spawn() itself, not an 'error' event. As a result, the child.on("error", () => finish(127)) handler at line 147 never runs. The throw happens inside the Promise executor, so it becomes a rejection, and setup-learning.ts exits with the bare message.
Minimal reproduction, Bun 1.4.3 on Windows 11:
import { spawn } from "node:child_process";
spawn("npx.cmd", ["--version"]); // throws: spawn npx.cmd EINVAL
spawn("npx.cmd", ["--version"], { shell: true }); // runs, prints 11.19.0
The server calls the same runCli from ensureLearningContainer at boot (server/src/index.ts:360) when a CLI login is present. Automatic container creation should therefore fail the same way on Windows, although I have only reproduced it through the setup helper.
Suggested fix
Run through the shell on Windows only:
{
cwd: directory,
env: cliEnvironment(),
shell: process.platform === "win32",
stdio: ["ignore", "pipe", "pipe"],
}
With shell: true the arguments are joined into a cmd.exe command line rather than passed as an argv. That is safe here because every caller passes literals (whoami, project list --json). cliEnvironment() already keeps COMSPEC, SystemRoot and PATHEXT, so cmd.exe resolves. macOS and Linux are unchanged.
Windows 11 Enterprise 10.0.26200, Bun 1.4.3, Node 24.21.0 / npm 11.19.0, OpenBot at 8c9ad4c. Related: #679 and #681 (other Windows checkout problems).
- Dominant language
- TypeScript
- Stars
- 6.6k
- Forks
- 914
- Avg merge
- 19h 22m
- Merged PRs (30d)
- 140
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from CopilotKit/OpenBot
-
Wrong key location at startupPossibly taken @charan-rathore claimed this 1 day ago. Open
Difficulty 1/5 Under an hour Newbie friendliness 68/100
CopilotKit/OpenBot#800 ·
Maintainers usually reply within 1 day
-
An HTML-only inbound email reaches its trigger with HTML character references left in the textPossibly taken @RaphaelFakhri claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 25/100
CopilotKit/OpenBot#806 ·
Maintainers usually reply within 1 day
-
Remote AG-UI Bots can't use the browser in chat: `computer_*` calls refused as "unavailable for this headless turn"Possibly taken @charan-rathore claimed this 1 day ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 68/100
CopilotKit/OpenBot#804 ·
Maintainers usually reply within 1 day
-
Five out-of-subject findings from PR #770's tier-3 review (credential-revoking tests, single-user boot gate, OAuth client rotation, shared-use atomicity, untyped server/tests)Possibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 4/5 Over a week Newbie friendliness 22/100
CopilotKit/OpenBot#786 ·
Maintainers usually reply within 1 day
-
server/tests leaks database connections: 55 files open a pool and never close itPossibly taken @adamsiwiec1 claimed this 4 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 70/100
CopilotKit/OpenBot#785 ·
Maintainers usually reply within 1 day
All issues in CopilotKit/OpenBot
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
ccch1mneyyy/dsh-TUI#1631 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
MiniMax-AI/minimax-code#507 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Transient OAuth login failure persists in getLoginStatus and masks active account in dashboardMay be free again A pull request for this issue was closed without being merged. Openaccount-pool bug gui
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
lidge-jun/opencodex#7378 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day