From c0e96bd1aa3878087bbe254f3c4adc6fd0bb6ad8 Mon Sep 17 00:00:00 2001 From: 7418 <7418@openclaw.ai> Date: Fri, 13 Feb 2026 16:48:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20resolve=20spawn=20EINVAL=20on=20Windows?= =?UTF-8?q?=20=E2=80=94=20filter=20undefined=20env=20values=20and=20skip?= =?UTF-8?q?=20.cmd=20wrappers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two root causes of spawn EINVAL on Windows: 1. process.env spread can include undefined values. Windows child_process.spawn requires all env values to be strings. sanitizeEnv now builds a clean object, dropping non-string entries. 2. Claude CLI installed via npm creates .cmd wrappers that cannot be spawned without shell:true. Detect .cmd/.bat extensions and fall back to SDK's internal resolution instead. Bump version to 0.10.7. Co-Authored-By: Claude Opus 4.6 --- package-lock.json | 4 ++-- package.json | 2 +- src/lib/claude-client.ts | 21 ++++++++++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53b95d8..e35d049 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codepilot", - "version": "0.10.6", + "version": "0.10.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codepilot", - "version": "0.10.6", + "version": "0.10.7", "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.33", "@hugeicons/core-free-icons": "^3.1.1", diff --git a/package.json b/package.json index 90b4341..4644cd1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codepilot", - "version": "0.10.6", + "version": "0.10.7", "private": true, "author": { "name": "op7418", diff --git a/src/lib/claude-client.ts b/src/lib/claude-client.ts index 05a6a5b..81c9fb2 100644 --- a/src/lib/claude-client.ts +++ b/src/lib/claude-client.ts @@ -35,15 +35,18 @@ function sanitizeEnvValue(value: string): string { /** * Sanitize all values in an env record so child_process.spawn won't - * throw EINVAL due to invalid characters (null bytes, control chars). + * throw EINVAL due to invalid characters or non-string values. + * On Windows, spawn is strict: every env value MUST be a string. + * Spreading process.env can include undefined values which cause EINVAL. */ function sanitizeEnv(env: Record): Record { + const clean: Record = {}; for (const [key, value] of Object.entries(env)) { if (typeof value === 'string') { - env[key] = sanitizeEnvValue(value); + clean[key] = sanitizeEnvValue(value); } } - return env; + return clean; } let cachedClaudePath: string | null | undefined; @@ -291,10 +294,18 @@ export function streamClaude(options: ClaudeStreamOptions): ReadableStream