diff --git a/src/main/services/OpenClawService.ts b/src/main/services/OpenClawService.ts index 43209ab826a..cf5afb82f83 100644 --- a/src/main/services/OpenClawService.ts +++ b/src/main/services/OpenClawService.ts @@ -8,7 +8,7 @@ import { exec } from '@expo/sudo-prompt' import { loggerService } from '@logger' import { isLinux, isMac, isWin } from '@main/constant' import { isUserInChina } from '@main/utils/ipService' -import { crossPlatformSpawn, executeCommand, findExecutableInEnv } from '@main/utils/process' +import { crossPlatformSpawn, executeCommand, findExecutableInEnv, stripProxyEnvVars } from '@main/utils/process' import getShellEnv, { refreshShellEnv } from '@main/utils/shell-env' import type { NodeCheckResult } from '@shared/config/types' import { IpcChannel } from '@shared/IpcChannel' @@ -491,9 +491,12 @@ class OpenClawService { let startupError: string | null = null let processExited = false + // Strip proxy env vars that crash OpenClaw's undici (e.g. socks5://). See #13140. + const gatewayEnv = { ...stripProxyEnvVars(shellEnv), OPENCLAW_CONFIG_PATH } + logger.info(`Spawning gateway process: ${openclawPath} gateway --port ${this.gatewayPort}`) this.gatewayProcess = crossPlatformSpawn(openclawPath, ['gateway', '--port', String(this.gatewayPort)], { - env: { ...shellEnv, OPENCLAW_CONFIG_PATH } + env: gatewayEnv }) logger.info(`Gateway process spawned with pid: ${this.gatewayProcess.pid}`) diff --git a/src/main/services/agents/services/claudecode/index.ts b/src/main/services/agents/services/claudecode/index.ts index 1753b6e1914..a0e7f30d645 100644 --- a/src/main/services/agents/services/claudecode/index.ts +++ b/src/main/services/agents/services/claudecode/index.ts @@ -19,7 +19,7 @@ import { validateModelId } from '@main/apiServer/utils' import { isWin } from '@main/constant' import { pluginService } from '@main/services/agents/plugins/PluginService' import { configManager } from '@main/services/ConfigManager' -import { autoDiscoverGitBash } from '@main/utils/process' +import { autoDiscoverGitBash, stripProxyEnvVars } from '@main/utils/process' import getLoginShellEnvironment from '@main/utils/shell-env' import { languageEnglishNameMap } from '@shared/config/languages' import { withoutTrailingApiVersion } from '@shared/utils' @@ -125,9 +125,7 @@ class ClaudeCodeService implements AgentServiceInterface { const apiConfig = await apiConfigService.get() const loginShellEnv = await getLoginShellEnvironment() - const loginShellEnvWithoutProxies = Object.fromEntries( - Object.entries(loginShellEnv).filter(([key]) => !key.toLowerCase().endsWith('_proxy')) - ) as Record + const loginShellEnvWithoutProxies = stripProxyEnvVars(loginShellEnv) // Auto-discover Git Bash path on Windows (already logs internally) const customGitBashPath = isWin ? autoDiscoverGitBash() : null diff --git a/src/main/utils/process.ts b/src/main/utils/process.ts index 4da7637206b..e036da37c04 100644 --- a/src/main/utils/process.ts +++ b/src/main/utils/process.ts @@ -667,3 +667,12 @@ export function getGitBashPathInfo(): GitBashPathInfo { return { path, source } } + +/** + * Strip proxy-related environment variables from an env object. + * Prevents child processes from inheriting proxy settings that may cause crashes + * (e.g. undici does not support socks5:// protocol). + */ +export function stripProxyEnvVars>(env: T): T { + return Object.fromEntries(Object.entries(env).filter(([key]) => !key.toLowerCase().endsWith('_proxy'))) as T +}