Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/main/services/OpenClawService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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}`)

Expand Down
6 changes: 2 additions & 4 deletions src/main/services/agents/services/claudecode/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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<string, string>
const loginShellEnvWithoutProxies = stripProxyEnvVars(loginShellEnv)

// Auto-discover Git Bash path on Windows (already logs internally)
const customGitBashPath = isWin ? autoDiscoverGitBash() : null
Expand Down
9 changes: 9 additions & 0 deletions src/main/utils/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T extends Record<string, string>>(env: T): T {
return Object.fromEntries(Object.entries(env).filter(([key]) => !key.toLowerCase().endsWith('_proxy'))) as T
}
Loading