From 788c356a252f59d7e97e45d857eee973edcca4d7 Mon Sep 17 00:00:00 2001 From: Lex Christopherson Date: Fri, 13 Mar 2026 09:12:01 -0600 Subject: [PATCH] fix: auto-detect headless environment for Playwright browser launch (#183) Browser launch was hardcoded to headless: false, crashing on Linux servers without a display server ($DISPLAY). Auto-detect headless environments and also support FORCE_HEADLESS=true override. Co-Authored-By: Claude Opus 4.6 --- src/resources/extensions/browser-tools/lifecycle.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/resources/extensions/browser-tools/lifecycle.ts b/src/resources/extensions/browser-tools/lifecycle.ts index e155f6e7b..d044ad7f3 100644 --- a/src/resources/extensions/browser-tools/lifecycle.ts +++ b/src/resources/extensions/browser-tools/lifecycle.ts @@ -181,7 +181,12 @@ export async function ensureBrowser(): Promise<{ browser: Browser; context: Brow // Lazy import so playwright is only loaded when actually needed const { chromium } = await import("playwright"); - const launchOptions: Record = { headless: false }; + // Auto-detect headless environments: Linux without $DISPLAY has no GUI. + // All browser tool operations (navigation, screenshots, DOM) work in headless mode. + const needsHeadless = process.platform === "linux" && !process.env.DISPLAY; + const launchOptions: Record = { + headless: needsHeadless || process.env.FORCE_HEADLESS === "true", + }; const customPath = process.env.BROWSER_PATH; if (customPath) launchOptions.executablePath = customPath; const browser = await chromium.launch(launchOptions);