openclaw - 💡(How to fix) Fix Doctor: Chrome version detection is flaky on macOS due to Gatekeeper cold-cache latency (2s timeout too tight)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

openclaw doctor --deep intermittently reports:

Could not determine the installed Chrome version. Chrome MCP requires Google Chrome 144+ on this host.

…even when a current Chrome (e.g. 148.x) is installed at the expected path, has no quarantine attribute, and is otherwise healthy. The warning is misleading because it implies a missing or out-of-date browser, when in reality it's a detection-side timeout.

Root Cause

…even when a current Chrome (e.g. 148.x) is installed at the expected path, has no quarantine attribute, and is otherwise healthy. The warning is misleading because it implies a missing or out-of-date browser, when in reality it's a detection-side timeout.

Fix Action

Fix / Workaround

Workaround for users

  • Run openclaw doctor --deep a second time within ~10 minutes; the warm cache satisfies the 2s budget.
  • Or manually verify:
    /usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" \
      "/Applications/Google Chrome.app/Contents/Info.plist"

Code Example

$ time "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version
Google Chrome 148.0.7778.179
"…/Google Chrome" --version  0.02s user 0.03s system 1% cpu 4.361 total

---

$ time "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version
0.01s user 0.01s system 87% cpu 0.019 total

---

function readBrowserVersion(executablePath) {
    const output = execText(executablePath, ["--version"], 2e3);  // 2-second timeout
    if (!output) return null;
    return output.replace(/\s+/g, " ").trim();
}

---

function readChromeVersionMac(appBundlePath) {
    try {
        const plist = path.join(appBundlePath, 'Contents', 'Info.plist');
        const v = execText('/usr/libexec/PlistBuddy', ['-c', 'Print :CFBundleShortVersionString', plist], 500);
        return v?.trim() || null;
    } catch { return null; }
}

---

/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" \
    "/Applications/Google Chrome.app/Contents/Info.plist"
RAW_BUFFERClick to expand / collapse

Doctor: Chrome version detection is flaky on macOS due to Gatekeeper cold-cache latency

Summary

openclaw doctor --deep intermittently reports:

Could not determine the installed Chrome version. Chrome MCP requires Google Chrome 144+ on this host.

…even when a current Chrome (e.g. 148.x) is installed at the expected path, has no quarantine attribute, and is otherwise healthy. The warning is misleading because it implies a missing or out-of-date browser, when in reality it's a detection-side timeout.

Repro

  • macOS 26.4.1 (arm64), Apple Silicon (M5 Max)
  • OpenClaw 2026.5.20 (e510042), npm install
  • Chrome stable 148.0.7778.179 at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
  • No quarantine xattr on the bundle.

Cold-cache run (e.g. after reboot or after macOS evicts the codesigning cache):

$ time "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version
Google Chrome 148.0.7778.179
"…/Google Chrome" --version  0.02s user 0.03s system 1% cpu 4.361 total

→ wall-clock 4.36s, CPU 0.05s. The wait is macOS Gatekeeper / amfid / notarization verification on the first spawn of a signed app since cache eviction.

Warm runs are <50ms:

$ time "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version
…  0.01s user 0.01s system 87% cpu 0.019 total

In dist/chrome.executables-…js:

function readBrowserVersion(executablePath) {
    const output = execText(executablePath, ["--version"], 2e3);  // 2-second timeout
    if (!output) return null;
    return output.replace(/\s+/g, " ").trim();
}

The 2-second execText timeout reliably aborts cold-cache calls on macOS, returning null, which doctor surfaces as the "Could not determine" warning.

Impact

  • False-positive in doctor --deep output, which masks real problems.
  • After a doctor run (warm cache), the warning disappears, creating an "I can't reproduce" support pattern.
  • Users who don't dig in may assume Chrome MCP is broken when it's actually fine.

Suggested fixes (any one is enough; combining is best)

1. Read the bundle Info.plist on macOS first (fast, deterministic)

Info.plist contains CFBundleShortVersionString. No process spawn, no Gatekeeper involvement:

function readChromeVersionMac(appBundlePath) {
    try {
        const plist = path.join(appBundlePath, 'Contents', 'Info.plist');
        const v = execText('/usr/libexec/PlistBuddy', ['-c', 'Print :CFBundleShortVersionString', plist], 500);
        return v?.trim() || null;
    } catch { return null; }
}

Measured 6ms vs cold spawn 4.36s. Same answer (148.0.7778.179). Falls through to --version if PlistBuddy or the plist is missing.

Equivalent on Linux: dpkg -s google-chrome-stable | grep Version, /opt/google/chrome/cron/google-chrome parsing, or a .deb metadata lookup. On Windows: wmic datafile where name="C:\\\\Program Files\\\\..." get Version or (Get-Item …).VersionInfo.ProductVersion.

2. Raise the --version timeout from 2s to ≥5s

macOS Gatekeeper cold-cache verification on Apple Silicon can spike to 3–6 seconds the first time a signed binary is spawned after kextcache/codesigning state churn. 2 seconds is too tight. 5–8 seconds would absorb the common case without making doctor feel sluggish on the happy path.

3. Treat a "no version" result as a separate, lower-severity finding

If neither plist nor --version works, doctor should distinguish:

  • "Chrome not installed" (path doesn't exist) → real warning.
  • "Chrome found but version probe timed out" → informational, with hint xattr / cold-cache.

Currently they collapse into the same string, which is what confused us.

Workaround for users

  • Run openclaw doctor --deep a second time within ~10 minutes; the warm cache satisfies the 2s budget.
  • Or manually verify:
    /usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" \
      "/Applications/Google Chrome.app/Contents/Info.plist"

Environment

  • OpenClaw: 2026.5.20 (e510042), pnpm install, up-to-date
  • OS: macOS 26.4.1 (arm64)
  • Node: v26.0.0
  • Chrome: 148.0.7778.179 stable
  • Source path: dist/chrome.executables-QEb7iBGo.js:561 (function readBrowserVersion)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Doctor: Chrome version detection is flaky on macOS due to Gatekeeper cold-cache latency (2s timeout too tight)