Bug
When running openclaw --profile <name> gateway status from within a gateway process that has OPENCLAW_LAUNCHD_LABEL set in its environment, the status command resolves the wrong plist file and displays the wrong service info.
Root Cause
applyCliProfileEnv() in src/cli/profile.ts sets OPENCLAW_PROFILE when --profile is passed, but does not clear OPENCLAW_LAUNCHD_LABEL. The label resolution in resolveLaunchAgentLabel() checks OPENCLAW_LAUNCHD_LABEL first and short-circuits before ever reading OPENCLAW_PROFILE:
function resolveLaunchAgentLabel(args) {
const envLabel = args?.env?.OPENCLAW_LAUNCHD_LABEL?.trim();
if (envLabel) return assertValidLaunchAgentLabel(envLabel); // ← always wins
return assertValidLaunchAgentLabel(resolveGatewayLaunchAgentLabel(args?.env?.OPENCLAW_PROFILE));
}
Since gateway processes typically set OPENCLAW_LAUNCHD_LABEL to their own label (e.g. ai.openclaw.batch), any CLI invocation from within that process inherits this value and always resolves to the same plist regardless of --profile.
Reproduction
On a multi-profile setup (interactive/ops/batch), from inside any gateway shell session:
# All three show the same plist (the one matching OPENCLAW_LAUNCHD_LABEL)
openclaw --profile interactive gateway status
openclaw --profile ops gateway status
openclaw --profile batch gateway status
# Workaround: unsetting the label fixes it
OPENCLAW_LAUNCHD_LABEL= openclaw --profile interactive gateway status # ✅ correct
Expected
Each --profile <name> gateway status should resolve to its own plist (ai.openclaw.<name>.plist) and display the correct port, config, and service info.
Suggested Fix
In applyCliProfileEnv(), when --profile is explicitly provided, delete (or re-derive) OPENCLAW_LAUNCHD_LABEL:
function applyCliProfileEnv(params) {
const env = params.env ?? process.env;
// ...
env.OPENCLAW_PROFILE = profile;
delete env.OPENCLAW_LAUNCHD_LABEL; // ← clear stale inherited label
// ...
}
This allows resolveLaunchAgentLabel to fall through to OPENCLAW_PROFILE and derive the correct label.
Impact
Display-only bug. Actual gateway services are correctly installed and running — only the CLI status display is affected.
Environment
- OpenClaw 2026.4.11 (769908e)
- macOS (Darwin 25.3.0, arm64)
- Multi-profile setup with 3 gateways (interactive, ops, batch)
Bug
When running
openclaw --profile <name> gateway statusfrom within a gateway process that hasOPENCLAW_LAUNCHD_LABELset in its environment, the status command resolves the wrong plist file and displays the wrong service info.Root Cause
applyCliProfileEnv()insrc/cli/profile.tssetsOPENCLAW_PROFILEwhen--profileis passed, but does not clearOPENCLAW_LAUNCHD_LABEL. The label resolution inresolveLaunchAgentLabel()checksOPENCLAW_LAUNCHD_LABELfirst and short-circuits before ever readingOPENCLAW_PROFILE:Since gateway processes typically set
OPENCLAW_LAUNCHD_LABELto their own label (e.g.ai.openclaw.batch), any CLI invocation from within that process inherits this value and always resolves to the same plist regardless of--profile.Reproduction
On a multi-profile setup (interactive/ops/batch), from inside any gateway shell session:
Expected
Each
--profile <name> gateway statusshould resolve to its own plist (ai.openclaw.<name>.plist) and display the correct port, config, and service info.Suggested Fix
In
applyCliProfileEnv(), when--profileis explicitly provided, delete (or re-derive)OPENCLAW_LAUNCHD_LABEL:This allows
resolveLaunchAgentLabelto fall through toOPENCLAW_PROFILEand derive the correct label.Impact
Display-only bug. Actual gateway services are correctly installed and running — only the CLI status display is affected.
Environment