fix(browser): skip port ownership check for remote CDP profiles (#28780)

* fix(browser): skip port ownership check for remote CDP profiles

When a browser profile has a non-loopback cdpUrl (e.g. Browserless,
Kubernetes sidecar, or any external CDP service), the port-ownership
check incorrectly fires because we don't "own" the remote process.
This causes "Port is in use but not by openclaw" even though the
remote CDP service is working and reachable.

Guard the ownership error with !remoteCdp so remote profiles fall
through to the WebSocket retry/attach logic instead.

Fixes #15582

* fix: add TypeScript null guard for profileState.running

* chore(changelog): note remote CDP ownership fix credits

Refs #15582

* Update CHANGELOG.md

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
Jannes Stubbemann
2026-03-02 07:00:16 +01:00
committed by GitHub
parent cda119b052
commit 5bb26bf22a
2 changed files with 12 additions and 2 deletions

View File

@@ -333,8 +333,9 @@ function createProfileContext(
return;
}
// HTTP responds but WebSocket fails - port in use by something else
if (!profileState.running) {
// HTTP responds but WebSocket fails - port in use by something else.
// Skip this check for remote CDP profiles since we never own the remote process.
if (!profileState.running && !remoteCdp) {
throw new Error(
`Port ${profile.cdpPort} is in use for profile "${profile.name}" but not by openclaw. ` +
`Run action=reset-profile profile=${profile.name} to kill the process.`,
@@ -356,6 +357,14 @@ function createProfileContext(
);
}
// At this point profileState.running is always non-null: the !remoteCdp guard
// above throws when running is null, and the remoteCdp path always exits via
// the attachOnly/remoteCdp block. Add an explicit guard for TypeScript.
if (!profileState.running) {
throw new Error(
`Unexpected state for profile "${profile.name}": no running process to restart.`,
);
}
await stopOpenClawChrome(profileState.running);
setProfileRunning(null);