← Back to PRs

#21459: fix(gateway): resolve port from profile config, not inherited env

by kkeeling open 2026-02-19 23:58 View on GitHub →
gateway cli size: M
## Summary Fixes two bugs that prevent running multiple OpenClaw gateway instances on the same machine using `--profile`. Closes #17833 ## Bug 1 — `OPENCLAW_GATEWAY_PORT` env var leaks between profiles **Root cause:** `startGatewayServer()` sets `process.env.OPENCLAW_GATEWAY_PORT` so child processes can discover the running port. When a second gateway starts under a different profile, it inherits this env var, causing `resolveGatewayPort()` to return the parent's port before reaching the profile's own config. **Fix (`src/cli/profile.ts`):** `applyCliProfileEnv` now deletes `OPENCLAW_GATEWAY_PORT` unconditionally before applying profile defaults. This lets `resolveGatewayPort` fall through to the profile's config (or `DEFAULT_GATEWAY_PORT`). The `--port` CLI flag is unaffected because it's passed as a `portOverride` that bypasses `resolveGatewayPort` entirely. For the `dev` profile, the port is then unconditionally set to 19001. ## Bug 2 — `OPENCLAW_PROFILE` env var doesn't derive state/config paths **Root cause:** `entry.ts` only called `applyCliProfileEnv` when `--profile` was in argv. When the profile was set via `OPENCLAW_PROFILE=morebetter` env var, `applyCliProfileEnv` never ran, so `OPENCLAW_STATE_DIR` and `OPENCLAW_CONFIG_PATH` were never derived, causing everything to fall back to `~/.openclaw/`. **Fix (`src/entry.ts`):** Compute an `effectiveProfile` from the flag value OR the `OPENCLAW_PROFILE` env var. Only strip `--profile` from argv when it was actually in argv (not env-sourced). ## ⚠️ Behavior Change The `dev` profile test previously expected `OPENCLAW_GATEWAY_PORT=19099` to be preserved (testing that explicit env values were not overridden). With this fix, `applyCliProfileEnv` now **unconditionally clears** `OPENCLAW_GATEWAY_PORT` before applying profile defaults, so the dev profile port changes from the inherited `19099` to the profile-configured `19001`. This is the correct behavior — the old test was accidentally validating the bug (inherited port winning over profile config). ## Tests - Updated `src/cli/profile.test.ts`: renamed the "does not override explicit env values" test to clarify that `OPENCLAW_GATEWAY_PORT` is intentionally cleared; added new test for non-dev profile port clearing. - Added `resolveGatewayPort` unit tests in `src/config/paths.test.ts`: env-over-config, config fallback, `DEFAULT_GATEWAY_PORT`, invalid env values, zero port, and profile-isolation scenario (8 new tests). - All 635 existing tests pass. <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes two critical bugs that prevented running multiple gateway instances with different profiles on the same machine. The changes ensure proper environment variable isolation between profiles by clearing inherited service-scoped env vars (`OPENCLAW_GATEWAY_PORT`, `OPENCLAW_LAUNCHD_LABEL`, `OPENCLAW_SYSTEMD_UNIT`, `OPENCLAW_SERVICE_VERSION`) before applying profile defaults. Also fixes `OPENCLAW_PROFILE` env var handling to derive state/config paths correctly. Additionally makes `gateway start` idempotent to prevent session disruption. Key changes: - `applyCliProfileEnv` now unconditionally clears inherited service env vars for profile isolation - `entry.ts` now computes effectiveProfile from both `--profile` flag and `OPENCLAW_PROFILE` env var - `runServiceStart` now returns "already-running" instead of restarting when service is loaded - Comprehensive test coverage added (8 new `resolveGatewayPort` tests, updated profile tests, idempotency test) <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - fixes critical bugs with comprehensive test coverage - The implementation is well-tested with 8 new unit tests for `resolveGatewayPort`, updated profile tests validating the new clearing behavior, and an idempotency test for `runServiceStart`. The fixes address real bugs that prevent multi-profile usage and session disruption. The behavior change is intentional and correctly documented in tests. All 635 existing tests pass. - No files require special attention <sub>Last reviewed commit: ff76554</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs