Skip to content

daemon: skip malformed/empty DevToolsActivePort instead of crashing#456

Open
thomwolf wants to merge 4 commits into
browser-use:mainfrom
thomwolf:fix/devtoolsactiveport-malformed-skip
Open

daemon: skip malformed/empty DevToolsActivePort instead of crashing#456
thomwolf wants to merge 4 commits into
browser-use:mainfrom
thomwolf:fix/devtoolsactiveport-malformed-skip

Conversation

@thomwolf

@thomwolf thomwolf commented Jun 19, 2026

Copy link
Copy Markdown

Problem

get_ws_url() iterates PROFILES and parses each DevToolsActivePort with .split("\n", 1). An empty or single-line file — e.g. a stale Chrome-CDP profile left behind by a prior run — returns fewer than 2 values, raising ValueError.

That exception wasn't caught, so a single malformed file aborted the entire discovery loop before reaching a valid profile. It surfaced as the cryptic daemon-fatal:

fatal: not enough values to unpack (expected 2, got 1)

This is easy to hit because Chrome-CDP is the first entry in PROFILES (added in a9ba3b9), so a leftover empty port file there shadows the user's real, working Chrome profile.

Fix

Catch ValueError alongside FileNotFoundError/NotADirectoryError so a malformed profile is skipped and discovery falls through to the next one — and ultimately to the actionable DevToolsActivePort not found — enable chrome://inspect... message.

Test

daemon.PROFILES = [Path("/tmp/empty-profile")]  # contains an empty DevToolsActivePort
daemon.get_ws_url()
# before: ValueError: not enough values to unpack (expected 2, got 1)
# after:  RuntimeError: DevToolsActivePort not found in [...] — enable chrome://inspect/#remote-debugging

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Skip malformed or empty DevToolsActivePort files during CDP discovery to prevent crashes and keep scanning for a valid profile. Also prioritize a dedicated `Chrome-CDP` profile in `PROFILES` to support headless Chrome 148+.

- **Bug Fixes**
  - Catch `ValueError` when parsing `DevToolsActivePort`; skip bad profiles and continue discovery.
  - Replaces the fatalnot enough values to unpackwith the normalDevToolsActivePort not foundenable chrome://inspect…” guidance.

- **Docs**
  - Added `interaction-skills/headless-automation.md` (non-default `--user-data-dir`, headless port file synthesis, launcher script, launchd example).
  - New domain guides: `domain-skills/angellist/investor-portfolio.md`, `domain-skills/x.com/articles.md`, `domain-skills/x.com/bookmarks.md`.
  - Updated `SKILL.md` with a link to headless automation and two Chrome gotchas (148+ `--remote-debugging-port` restriction, `--headless=new` not writing `DevToolsActivePort`).

<sup>Written for commit 16943d9faa124d47e7bd79427c4cc9252fbf36f1. Summary will update on new commits.</sup>

<a href="https://cubic.dev/pr/browser-use/browser-harness/pull/456?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

thomwolf and others added 4 commits May 26, 2026 17:55
Chrome 148+ silently ignores --remote-debugging-port when the user-data-dir
is the default Chrome profile. Workaround is a dedicated profile dir (cloned
from the user's main profile to preserve logins) launched headless. This
adds that dir to PROFILES so the harness can discover the live port without
needing BU_CDP_WS set explicitly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Walks through the three non-obvious things needed to run the harness
unattended against a real (logged-in) profile: the Chrome 148+
--user-data-dir requirement, that --headless=new doesn't write
DevToolsActivePort, and the ditto-clone-then-strip-Singleton trick to
preserve logins. Includes the launcher-script + launchd plist used in
production. Two new gotchas in SKILL.md point at the file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
get_ws_url() iterates PROFILES and parses each DevToolsActivePort with
`.split("\n", 1)`. An empty or single-line file (e.g. a stale Chrome-CDP
profile left by a prior run) returns <2 values, raising ValueError. That
error wasn't caught, so a single malformed file aborted the whole
discovery loop before reaching a valid profile — surfacing as the cryptic
"fatal: not enough values to unpack (expected 2, got 1)".

Catch ValueError alongside FileNotFoundError/NotADirectoryError so a bad
profile is skipped and discovery falls through to the next one (and
ultimately to the actionable "DevToolsActivePort not found" message).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@browser-harness-review

Copy link
Copy Markdown

✅ Skill review passed

Reviewed 5 file(s) — no findings.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="daemon.py">

<violation number="1" location="daemon.py:66">
P2: The `except ValueError` guard is incomplete: a two-line `DevToolsActivePort` with a non-numeric port (e.g. `abc\n/devtools/browser/...`) passes the `split()` step, then later crashes at `int(port.strip())` inside the inner `try` that only catches `OSError`. This still aborts profile fallback, defeating the PR's goal of skipping all malformed files.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread daemon.py
port, path = (base / "DevToolsActivePort").read_text().strip().split("\n", 1)
except (FileNotFoundError, NotADirectoryError):
continue
except ValueError:

@cubic-dev-ai cubic-dev-ai Bot Jun 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The except ValueError guard is incomplete: a two-line DevToolsActivePort with a non-numeric port (e.g. abc\n/devtools/browser/...) passes the split() step, then later crashes at int(port.strip()) inside the inner try that only catches OSError. This still aborts profile fallback, defeating the PR's goal of skipping all malformed files.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At daemon.py, line 66:

<comment>The `except ValueError` guard is incomplete: a two-line `DevToolsActivePort` with a non-numeric port (e.g. `abc\n/devtools/browser/...`) passes the `split()` step, then later crashes at `int(port.strip())` inside the inner `try` that only catches `OSError`. This still aborts profile fallback, defeating the PR's goal of skipping all malformed files.</comment>

<file context>
@@ -62,6 +63,9 @@ def get_ws_url():
             port, path = (base / "DevToolsActivePort").read_text().strip().split("\n", 1)
         except (FileNotFoundError, NotADirectoryError):
             continue
+        except ValueError:
+            # malformed/empty DevToolsActivePort (stale profile) — skip, try next
+            continue
</file context>
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant