Skip to content

Gateway LaunchAgent plist loses custom NODE_OPTIONS after openclaw update #22663

@kevintee23

Description

@kevintee23

Summary

openclaw update regenerates the LaunchAgent plist (~/Library/LaunchAgents/ai.openclaw.gateway.plist) from scratch, wiping out any custom EnvironmentVariables entries. There's no config path to persist custom env vars across updates.

This is a problem because Node.js 22+ requires workarounds for broken IPv6 dual-stack behavior on networks where IPv6 is unreachable. Without the workaround, the gateway's Telegram channel (and likely any outbound HTTPS to hosts with AAAA records) fails with "Network request for '...' failed!" / ETIMEDOUT.

Environment

  • OpenClaw: 2026.2.19-2 (stable, npm)
  • Node.js: v24.4.0
  • macOS: 26.2 (arm64)
  • Gateway: LaunchAgent (ai.openclaw.gateway)

Steps to reproduce

  1. Have a network where IPv6 is not fully routable (common on residential networks)
  2. Add NODE_OPTIONS to the gateway plist:
    <key>NODE_OPTIONS</key>
    <string>--dns-result-order=ipv4first --no-network-family-autoselection</string>
  3. Verify Telegram works: openclaw healthTelegram: ok
  4. Run openclaw update (even if already on the latest version)
  5. openclaw healthTelegram: failed (unknown) - fetch failed

Root cause

Node.js 22+ enables autoSelectFamily by default, which tries IPv6 and IPv4 connections simultaneously. When IPv6 is unreachable (EHOSTUNREACH), the fallback to IPv4 is broken — the IPv4 attempt also times out (ETIMEDOUT), even though direct IPv4 TCP connections succeed.

Evidence:

  • curl https://api.telegram.org/bot.../getMe → works (system networking handles fallback correctly)
  • node -e "fetch('https://api.telegram.org/...')"ETIMEDOUT (both IPv4 and IPv6 fail)
  • node -e "net.connect(443, '149.154.166.110', ...)" → works (raw TCP to IPv4 is fine)
  • NODE_OPTIONS="--dns-result-order=ipv4first --no-network-family-autoselection" node -e "fetch(...)" → works

Suggested fix

One or more of:

  1. Persist custom env vars: Support a config path like gateway.launchAgent.env (or gateway.nodeOptions) that gets merged into the plist on update/regeneration.
  2. Detect and apply the workaround automatically: If the gateway detects ETIMEDOUT on Telegram/outbound HTTPS and IPv6 is unreachable, log a hint or auto-set --no-network-family-autoselection.
  3. Set --no-network-family-autoselection by default: Since autoSelectFamily is known to be problematic on many networks, the gateway could default to disabling it in the generated plist.

Current workaround

Manually patch the plist after each update:

# Add to EnvironmentVariables in ~/Library/LaunchAgents/ai.openclaw.gateway.plist:
<key>NODE_OPTIONS</key>
<string>--dns-result-order=ipv4first --no-network-family-autoselection</string>

# Then restart:
openclaw gateway restart

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions