From 0cc7d13213a71e45acc5b0c19b00bc001e21caf5 Mon Sep 17 00:00:00 2001 From: LR Date: Fri, 29 May 2026 16:47:35 +0800 Subject: [PATCH 1/2] fix(agents): quote bin path on Windows to support spaces in PATH On Windows, `spawn` with `shell: true` concatenates the binary path and argv into a single command string. When the resolved binary lives under a directory with spaces (e.g. `C:\Program Files\...`), cmd.exe splits on the space and fails with "'C:\Program' is not recognized". Fix: wrap `bin` in double quotes when spawning through a shell. Co-Authored-By: Claude Opus 4.7 --- next/src/lib/agents/invoke.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/next/src/lib/agents/invoke.ts b/next/src/lib/agents/invoke.ts index 6626592..78c7903 100644 --- a/next/src/lib/agents/invoke.ts +++ b/next/src/lib/agents/invoke.ts @@ -158,18 +158,20 @@ export function invokeAgent(opts: InvokeOpts): ReadableStream { if (promptViaMessageFlag) argv = [...argv, "--message", opts.prompt]; try { - child = spawn(bin!, argv, { + // On Windows, `spawn` cannot launch a `.cmd` / `.bat` shim (which is + // what npm installs for most CLI agents) without going through the + // shell. Without this, every agent invocation fails with + // EINVAL / "spawn 无效的参数". macOS/Linux use direct exec. + // Safety: prompt content is delivered via stdin or `--message + // ` (argv-message), not interpolated into a shell command, + // so this does not introduce a shell-injection vector. + const useShell = process.platform === "win32"; + child = spawn(useShell ? `"${bin}"` : bin!, argv, { cwd: opts.cwd ?? process.cwd(), env, stdio: ["pipe", "pipe", "pipe"], - // On Windows, `spawn` cannot launch a `.cmd` / `.bat` shim (which is - // what npm installs for most CLI agents) without going through the - // shell. Without this, every agent invocation fails with - // EINVAL / "spawn 无效的参数". macOS/Linux use direct exec. - // Safety: prompt content is delivered via stdin or `--message - // ` (argv-message), not interpolated into a shell command, - // so this does not introduce a shell-injection vector. - shell: process.platform === "win32", + shell: useShell, + windowsVerbatimArguments: false, }); } catch (err) { safeEnqueue({ From 1e2c9df9387f7c889ed42b77f499003744e44c2a Mon Sep 17 00:00:00 2001 From: LR Date: Mon, 1 Jun 2026 09:34:20 +0800 Subject: [PATCH 2/2] fix(agents): quote bin path in openclaw detection for Windows spaces --- next/src/lib/agents/detect.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/next/src/lib/agents/detect.ts b/next/src/lib/agents/detect.ts index c72c8db..ef0b0d6 100644 --- a/next/src/lib/agents/detect.ts +++ b/next/src/lib/agents/detect.ts @@ -360,9 +360,10 @@ export async function resolveOpenclawAgentId(bin: string): Promise { try { const { spawn } = await import("node:child_process"); const out = await new Promise((res, rej) => { - const child = spawn(bin, ["agents", "list"], { + const useShell = process.platform === "win32"; + const child = spawn(useShell ? `"${bin}"` : bin, ["agents", "list"], { stdio: ["ignore", "pipe", "pipe"], - shell: process.platform === "win32", + shell: useShell, }); let buf = ""; child.stdout.setEncoding("utf8");