From 7ab3d2ecb6cb5f331f7749a69091f0a29068c217 Mon Sep 17 00:00:00 2001 From: roboomp Date: Thu, 30 Jul 2026 05:19:18 +0000 Subject: [PATCH] fix(browser): cleaned headless profile after failed launch Remove the OMP-owned Chromium user-data directory when executable resolution or puppeteer launch fails before a browser handle exists. Fixes #7058 --- .../coding-agent/src/tools/browser/launch.ts | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/coding-agent/src/tools/browser/launch.ts b/packages/coding-agent/src/tools/browser/launch.ts index 26615b293..8c9e3c033 100644 --- a/packages/coding-agent/src/tools/browser/launch.ts +++ b/packages/coding-agent/src/tools/browser/launch.ts @@ -338,16 +338,23 @@ export async function launchHeadlessBrowser(opts: LaunchHeadlessOptions): Promis userDataDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "omp-chrome-profile-")); launchArgs.push(`--user-data-dir=${userDataDir}`); } - const executablePath = await ensureChromiumExecutable(); - const browser = await puppeteer.launch({ - headless: opts.headless, - defaultViewport: opts.headless ? initialViewport : null, - executablePath, - args: launchArgs, - ignoreDefaultArgs: [...new Set([...stealthIgnoreDefaultArgs(executablePath), ...(opts.ignoreDefaultArgs ?? [])])], - protocolTimeout: BROWSER_PROTOCOL_TIMEOUT_MS, - }); - return { browser, userDataDir }; + try { + const executablePath = await ensureChromiumExecutable(); + const browser = await puppeteer.launch({ + headless: opts.headless, + defaultViewport: opts.headless ? initialViewport : null, + executablePath, + args: launchArgs, + ignoreDefaultArgs: [ + ...new Set([...stealthIgnoreDefaultArgs(executablePath), ...(opts.ignoreDefaultArgs ?? [])]), + ], + protocolTimeout: BROWSER_PROTOCOL_TIMEOUT_MS, + }); + return { browser, userDataDir }; + } catch (error) { + if (userDataDir) await removeUserDataDir(userDataDir); + throw error; + } } /**