From 4f40025b9d835986e752fc5918ab2152487cf8db Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:53:25 +0000 Subject: [PATCH 1/2] =?UTF-8?q?fix(ai):=20frontend=20console=20error=20?= =?UTF-8?q?=E2=80=94=20strip=20xs=20on=20localhost=20(agent)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Diagnosed a CORS error on local development environment caused by WebTorrent fetching `.torrent` files from R2 buckets (via `xs` parameter) that do not allow localhost origin. Modified `js/webtorrent.js` to strip the `xs` parameter from magnet links when running on `localhost` or `127.0.0.1`. This prevents the browser from attempting the blocked fetch request, resolving the console error while maintaining functionality (falling back to DHT/peers). Verified using `scripts/agent/debug_frontend.py` which captures frontend console logs via Playwright. Tests run: - `npm run lint` - `npm run test:unit:shard1` - `python3 scripts/agent/debug_frontend.py` (verified error is gone) Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/webtorrent.js | 42 +++++++++++++++++++++++++++++---- scripts/agent/debug_frontend.py | 18 ++++---------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/js/webtorrent.js b/js/webtorrent.js index 8fbaf4b8..d4f8698d 100644 --- a/js/webtorrent.js +++ b/js/webtorrent.js @@ -27,6 +27,29 @@ import { infoHashFromMagnet } from "./magnets.js"; const DEFAULT_PROBE_TRACKERS = Object.freeze([...WSS_TRACKERS]); +function stripXsParameter(magnetURI) { + const trimmed = typeof magnetURI === "string" ? magnetURI.trim() : ""; + if ( + typeof window !== "undefined" && + (window.location.hostname === "localhost" || + window.location.hostname === "127.0.0.1") + ) { + try { + const [prefix, queryString] = trimmed.split("?"); + if (queryString) { + const params = new URLSearchParams(queryString); + if (params.has("xs")) { + params.delete("xs"); + return `${prefix}?${params.toString()}`; + } + } + } catch (err) { + // ignore + } + } + return trimmed; +} + function normalizeTrackerList(trackers) { const normalized = []; const seen = new Set(); @@ -184,7 +207,8 @@ export class TorrentClient { magnetURI, { timeoutMs = 8000, maxWebConns = 2, polls = 2, urlList = [] } = {} ) { - const magnet = typeof magnetURI === "string" ? magnetURI.trim() : ""; + const magnet = stripXsParameter(magnetURI); + if (!magnet) { return { healthy: false, @@ -903,7 +927,17 @@ export class TorrentClient { */ async streamVideo(magnetURI, videoElement, opts = {}) { try { - emit("torrent-stream-start", { magnet: magnetURI }); + const effectiveMagnetURI = stripXsParameter(magnetURI); + if ( + effectiveMagnetURI !== + (typeof magnetURI === "string" ? magnetURI.trim() : "") + ) { + this.log( + "[WebTorrent] Stripped 'xs' parameter to prevent CORS errors on localhost.", + ); + } + + emit("torrent-stream-start", { magnet: effectiveMagnetURI }); // 1) Make sure we have a WebTorrent client and a valid SW registration. const initResult = await this.init(); @@ -942,7 +976,7 @@ export class TorrentClient { if (isFirefoxBrowser) { this.log("Starting torrent download (Firefox path)"); this.client.add( - magnetURI, + effectiveMagnetURI, { ...chromeOptions, maxWebConns: 4 }, (torrent) => { this.log("Torrent added (Firefox path):", torrent.name); @@ -951,7 +985,7 @@ export class TorrentClient { ); } else { this.log("Starting torrent download (Chrome path)"); - this.client.add(magnetURI, chromeOptions, (torrent) => { + this.client.add(effectiveMagnetURI, chromeOptions, (torrent) => { this.log("Torrent added (Chrome path):", torrent.name); this.handleChromeTorrent(torrent, videoElement, resolve, reject); }); diff --git a/scripts/agent/debug_frontend.py b/scripts/agent/debug_frontend.py index 8142f20b..0441d740 100644 --- a/scripts/agent/debug_frontend.py +++ b/scripts/agent/debug_frontend.py @@ -1,31 +1,21 @@ import sys -import time from playwright.sync_api import sync_playwright def run(): with sync_playwright() as p: - # Launch browser (headless by default) browser = p.chromium.launch() page = browser.new_page() - # Capture console messages page.on("console", lambda msg: print(f"console:{msg.type}: {msg.text}")) - - # Capture uncaught exceptions page.on("pageerror", lambda exc: print(f"pageerror: {exc}")) - - # Capture failed requests - page.on("requestfailed", lambda request: print(f"requestfailed: {request.url} {request.failure}")) + page.on("requestfailed", lambda req: print(f"requestfailed: {req.url} - {req.failure}")) try: - print("Navigating to http://localhost:8000...") page.goto("http://localhost:8000") - - # Wait for some time to catch initialization errors - time.sleep(5) - + # Wait a bit for JS to execute and errors to appear + page.wait_for_timeout(5000) except Exception as e: - print(f"Script error: {e}") + print(f"Error navigating: {e}") finally: browser.close() From 53a14a0dfeb720e91318a097269c5085373419c8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:57:43 +0000 Subject: [PATCH 2/2] fix(ai): cleanup logging and use effective magnet in webtorrent.js This commit refactors `js/webtorrent.js` to ensure the `stripXsParameter` helper is correctly used and its result (`effectiveMagnetURI`) is passed to `client.add()`. - Refactored logic to use `effectiveMagnetURI` variable. - Cleaned up conditional logging. - Ensured consistent usage in `streamVideo`. Tests run: - `npm run lint` - `npm run test:unit:shard1` - `python3 scripts/agent/debug_frontend.py` (verified error is gone) Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com>