fix(bypass): resolve Xlib namespace collision breaking CDP browser startup (#1099)

## Problem

The full (browser) image ships two conflicting distributions that both
own the top-level `Xlib/` namespace:

- **`python-xlib` 0.33** (2022) — pulled by the `browser` extra
- **`python3-xlib` 0.15** (2014) — pulled transitively via `pyautogui` →
`mouseinfo`

Both install into the same `Xlib/` directory, so install order decides
which files survive. When the 2014 `python3-xlib` lands last, `Xlib.X`
is missing the `FamilyServerInterpreted` attribute that the SeleniumBase
Pure-CDP driver references during browser startup. Every bypass attempt
then fails with:

```
Pure CDP browser startup failed: module 'Xlib.X' has no attribute 'FamilyServerInterpreted'
Bypasser error: RuntimeError: Pure CDP browser startup failed: module 'Xlib.X' has no attribute 'FamilyServerInterpreted'
```

Result: **all Cloudflare / DDoS-Guard protected downloads fail** on
affected builds.

## Fix

After the browser stack is installed, uninstall the stale `python3-xlib`
and force-reinstall `python-xlib==0.33` so it deterministically owns the
namespace. A build-time assertion checks
`Xlib.X.FamilyServerInterpreted` exists so the image fails fast if the
collision ever returns.

`pyautogui` operates correctly against `python-xlib` 0.33 (superset
API), so nothing else regresses.

## Testing

- Reproduced live: a build where `python3-xlib` won produced the exact
`FamilyServerInterpreted` error on every CDP browser start; removing it
and reinstating `python-xlib==0.33` immediately restored `Chrome browser
ready (Pure CDP)` and successful `_bypass_method_cdp_solve`.
- The new build-time assertion prints `Xlib namespace OK: (0, 33)` and
exits non-zero if the attribute is ever missing.
This commit is contained in:
Alex Schittko
2026-07-04 09:50:33 -04:00
committed by GitHub
parent b57925c39d
commit 8b4230ee9f
+15
View File
@@ -173,6 +173,21 @@ RUN apt-get update && \
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-default-groups --extra browser
# Deterministically resolve the Xlib namespace collision.
# pyautogui/mouseinfo pull the stale `python3-xlib` (0.15, 2014), while the
# `--extra browser` set pulls `python-xlib` (0.33). Both packages install into
# the same top-level `Xlib/` namespace, so whichever lands last wins. When the
# 2014 build wins, `Xlib.X` is missing `FamilyServerInterpreted`, which the
# SeleniumBase Pure-CDP driver requires at browser startup -> every bypass fails
# with "module 'Xlib.X' has no attribute 'FamilyServerInterpreted'" and no
# Cloudflare/DDoS-Guard protected download can complete. Drop the stale package
# and force python-xlib 0.33 to own the namespace. pyautogui runs fine against
# 0.33 (superset API).
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip uninstall --python /app/.venv/bin/python python3-xlib && \
uv pip install --python /app/.venv/bin/python --reinstall python-xlib==0.33 && \
/app/.venv/bin/python -c "import Xlib.X; assert hasattr(Xlib.X, 'FamilyServerInterpreted'), 'Xlib.X.FamilyServerInterpreted missing after fix'; print('Xlib namespace OK:', Xlib.__version__)"
# uv is only needed while building the image.
RUN rm -f /usr/bin/uv /usr/bin/uvx