Skip to content

fix(browser): set DISPLAY fallback for non-headless Chrome on Linux/WSL2#64547

Closed
Yanhu007 wants to merge 2 commits into
openclaw:mainfrom
Yanhu007:fix/browser-display-env-wsl
Closed

fix(browser): set DISPLAY fallback for non-headless Chrome on Linux/WSL2#64547
Yanhu007 wants to merge 2 commits into
openclaw:mainfrom
Yanhu007:fix/browser-display-env-wsl

Conversation

@Yanhu007
Copy link
Copy Markdown
Contributor

Summary

Fixes #64464 — Non-headless Chrome on WSL2 fails with Missing X server or $DISPLAY because the environment variable is unset.

Root Cause

WSL2 (especially with WSLg) often doesn't export DISPLAY to all shell contexts. The Chrome spawn in launchOpenClawChrome() passes process.env, which lacks DISPLAY. Chrome's X11/Ozone platform then fails:

ERROR:ui/ozone/platform/x11/ozone_platform_x11.cc:256] Missing X server or $DISPLAY
ERROR:ui/aura/env.cc:246] The platform failed to initialize. Exiting.

Fix

When all three conditions are met, fall back to DISPLAY=:0:

  1. Platform is Linux
  2. Headless mode is disabled
  3. process.env.DISPLAY is unset

:0 is the standard default for X11/Xwayland/WSLg displays. If the user has DISPLAY set, their value takes precedence (...process.env spread comes first).

No-op for other environments

  • Headless mode: skip (no display needed)
  • macOS/Windows: skip (no DISPLAY concept)
  • Linux with DISPLAY set: skip (existing value preserved)

The reply media path normalizer blocked absolute paths from the managed
OpenClaw temp directory (/tmp/openclaw/), causing TTS-generated audio
files to be silently dropped. This resulted in no reply being delivered
and a 60s typing indicator timeout.

The media loading allowlist (buildMediaLocalRoots) already includes the
preferredTmpDir, but the reply security check (isAllowedAbsoluteReplyMediaPath)
did not. Add the same check so the two allowlists are consistent.

Wraps resolvePreferredOpenClawTmpDir() in try/catch to gracefully degrade
in exotic environments where tmp dir resolution fails.

Fixes openclaw#64529
On WSL2, the DISPLAY environment variable is often not set by default.
When launching Chrome in non-headless mode, this causes the X11/Ozone
platform to fail with 'Missing X server or $DISPLAY'.

Fall back to DISPLAY=:0 (the standard X11 default) when the env var
is unset, the platform is Linux, and headless mode is disabled.
This matches the default for most X11/Xwayland/WSLg setups.

Fixes openclaw#64464
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 11, 2026

Greptile Summary

This PR fixes non-headless Chrome failing to start on Linux/WSL2 by injecting a DISPLAY=:0 fallback when DISPLAY is absent in the process environment, and separately allows TTS/tool-generated media files under the managed OpenClaw tmp dir to pass the reply media path check in reply-media-paths.ts.

Confidence Score: 5/5

Safe to merge — both changes are narrow, well-guarded, and address real runtime failures with no regressions in other environments.

The DISPLAY fallback is correctly scoped (Linux + non-headless + DISPLAY unset), evaluated at spawn time, and the spread order ensures existing values win. The reply-media-paths addition is wrapped in a try-catch so exotic environments fall through safely. No P0/P1 issues found.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(browser): set DISPLAY fallback for n..." | Re-trigger Greptile

@Yanhu007
Copy link
Copy Markdown
Contributor Author

Closing to rotate in newer fix. Will resubmit if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: browser control spawn chrome without setting env['DISPLAY'] = ':0' so chrome failed to initialize

1 participant