Fix NODE_EXTRA_CA_CERTS missing from LaunchAgent environment on macOS

launchd services do not inherit the shell environment, so Node's undici/fetch
cannot locate the macOS system CA bundle (/etc/ssl/cert.pem). This causes TLS
verification failures for all HTTPS requests (e.g. Telegram, webhooks) when the
gateway runs as a LaunchAgent, while the same gateway works fine in a terminal.

Add NODE_EXTRA_CA_CERTS defaulting to /etc/ssl/cert.pem on macOS in both
buildServiceEnvironment and buildNodeServiceEnvironment. User-supplied
NODE_EXTRA_CA_CERTS is always respected and takes precedence.

Fixes #22856

Co-authored-by: Clawborn <tianrun.yang103@gmail.com>
This commit is contained in:
Clawborn
2026-02-22 04:42:20 +08:00
committed by Ayaan Zaidi
parent 7bbfb9de5e
commit d33f24c4e9
2 changed files with 48 additions and 0 deletions

View File

@@ -248,11 +248,17 @@ export function buildServiceEnvironment(params: {
// Keep a usable temp directory for supervised services even when the host env omits TMPDIR.
const tmpDir = env.TMPDIR?.trim() || os.tmpdir();
const proxyEnv = readServiceProxyEnvironment(env);
// On macOS, launchd services don't inherit the shell environment, so Node's undici/fetch
// cannot locate the system CA bundle. Default to /etc/ssl/cert.pem so TLS verification
// works correctly when running as a LaunchAgent without extra user configuration.
const nodeCaCerts =
env.NODE_EXTRA_CA_CERTS ?? (process.platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
return {
HOME: env.HOME,
TMPDIR: tmpDir,
PATH: buildMinimalServicePath({ env }),
...proxyEnv,
NODE_EXTRA_CA_CERTS: nodeCaCerts,
OPENCLAW_PROFILE: profile,
OPENCLAW_STATE_DIR: stateDir,
OPENCLAW_CONFIG_PATH: configPath,
@@ -274,11 +280,17 @@ export function buildNodeServiceEnvironment(params: {
const configPath = env.OPENCLAW_CONFIG_PATH;
const tmpDir = env.TMPDIR?.trim() || os.tmpdir();
const proxyEnv = readServiceProxyEnvironment(env);
// On macOS, launchd services don't inherit the shell environment, so Node's undici/fetch
// cannot locate the system CA bundle. Default to /etc/ssl/cert.pem so TLS verification
// works correctly when running as a LaunchAgent without extra user configuration.
const nodeCaCerts =
env.NODE_EXTRA_CA_CERTS ?? (process.platform === "darwin" ? "/etc/ssl/cert.pem" : undefined);
return {
HOME: env.HOME,
TMPDIR: tmpDir,
PATH: buildMinimalServicePath({ env }),
...proxyEnv,
NODE_EXTRA_CA_CERTS: nodeCaCerts,
OPENCLAW_STATE_DIR: stateDir,
OPENCLAW_CONFIG_PATH: configPath,
OPENCLAW_LAUNCHD_LABEL: resolveNodeLaunchAgentLabel(),