Fix Playwright cleanup crash, CDP port conflicts, localhost IPv6, and URL null-string pollution#70
Open
andrii-mazurchuk wants to merge 2 commits into
Open
Fix Playwright cleanup crash, CDP port conflicts, localhost IPv6, and URL null-string pollution#70andrii-mazurchuk wants to merge 2 commits into
andrii-mazurchuk wants to merge 2 commits into
Conversation
Line endings: all Python source files converted from CRLF to LF. Bug fixes (detail.py, chrome.py, launcher.py, prompt.py): - enrich: catch Playwright cleanup crash on Ubuntu 26.04 when Chrome launch fails mid-batch; unprocessed jobs marked browser_unavailable - enrich: sanitize LLM-returned application_url — treat "None"/"null" strings as NULL, not as a valid URL - apply/chrome: derive stable per-instance CDP base port from MD5 hash of instance name so concurrent apply runs don't clobber each other - apply/launcher: use 127.0.0.1 instead of localhost for CDP endpoint (Ubuntu 26.04 resolves localhost to IPv6 ::1, Chrome binds IPv4 only) - apply/launcher: guard application_url against "None" string value - apply/prompt: look up site-specific password from profile.json personal.site_passwords before falling back to the default password Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four operational bugs found while running ApplyPilot on Ubuntu 26.04 with multiple concurrent instances.
1. Enrich stage crashes on exit when Chrome launch fails (
detail.py)Problem: When Playwright fails to launch Chrome mid-batch (e.g. because the system Chrome binary is unavailable), the cleanup path of
with sync_playwright() as p:raises'PlaywrightContextManager' object has no attribute '_playwright', propagating an unhandled exception that kills the entire enrich stage with exit 1.Fix: Wrap the
with sync_playwright() as p:block in a broadexcept Exceptionat the batch level. Any jobs that hadn't been processed yet are written to the DB asbrowser_unavailableso they can be retried, and the stage exits cleanly.2. CDP endpoint uses
localhostwhich resolves to IPv6 on Ubuntu 26.04 (launcher.py)Problem:
http://localhost:{port}in_make_mcp_config()resolves to::1(IPv6) on Ubuntu 26.04, but Chrome's remote debugging port only binds to127.0.0.1(IPv4). Result:ECONNREFUSED ::1:9222on every apply attempt.Fix: Replace
localhostwith127.0.0.1in the CDP endpoint URL.3. Concurrent apply runs on multiple instances share port 9222 (
chrome.py)Problem: All instances hard-code
BASE_CDP_PORT = 9222. When two instances run apply concurrently, one instance's_kill_on_port(9222)kills the other instance's Chrome mid-session.Fix: Derive a stable per-instance base port from the MD5 hash of the instance directory name, mapping each instance into a unique 10-port window in the range 9200–9399. Deterministic: same instance always gets the same port.
4. LLM returns
"None"string for missingapplication_url(detail.py,launcher.py,prompt.py)Problem: When no apply URL is found, the LLM returns the string
"None"rather than JSON null. Python'soroperator treats non-empty strings as truthy, soapplication_url = "None"passes all guards and gets stored in the DB and shown to the apply agent as a valid URL (URL: None), causing the agent to refuse to proceed.Fix:
detail.py: sanitize LLM output before writing — treat"None","null","N/A",""as NULLlauncher.py: guardapply_urlconstruction with explicit!= "None"checkprompt.py: same guard when building the URL line shown to the apply agent5. Site-specific password support (
prompt.py)Problem: Different job sites may require different account credentials but the profile only supports one global password.
Fix: Check
personal.get('site_passwords', {}).get(job_site, personal.get('password'))so per-site passwords inprofile.jsontake precedence over the default.Test environment
APPLYPILOT_DIRChecklist