← Back to PRs

#10589: fix: chrome extension install fails in bundled dist layout

by joetomasone open 2026-02-06 18:03 View on GitHub →
cli stale
## Problem `openclaw browser extension install` fails with: ``` Bundled Chrome extension is missing. Reinstall OpenClaw and try again. ``` ...even though `assets/chrome-extension/manifest.json` exists at the package root. ## Root Cause `resolveBundledExtensionRootDir()` has a walk-up loop that searches parent directories for `assets/chrome-extension`, with a hardcoded fallback of `../../assets/chrome-extension`. The bundler (Rollup/esbuild) tree-shakes the walk-up loop, leaving only the hardcoded fallback. This fallback is correct for the **source** layout (`src/cli/` = 2 levels deep) but wrong for the **bundled** layout (`dist/` = 1 level deep): | Layout | `here` | `../../assets/chrome-extension` resolves to | |--------|--------|----------------------------------------------| | Source | `src/cli/` | `./assets/chrome-extension` ✅ | | Bundled | `dist/` | `../assets/chrome-extension` ❌ (one level above package root) | ## Fix Add a secondary fallback after the walk-up loop that tries both `../../` and `../` relative offsets with `manifest.json` existence checks. This is resilient to tree-shaking since it doesn't depend on the loop surviving bundling — both candidate paths are checked at runtime. ## Test Added a test case for the flat `dist/` (bundled) layout alongside the existing `src/cli/` tests. ## Verified Manually patched the compiled `dist/` files on a Homebrew-installed OpenClaw 2026.2.3-1 (macOS, Apple Silicon) and confirmed `openclaw browser extension install` succeeds after the fix. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> - Updates `resolveBundledExtensionRootDir()` to locate the bundled Chrome extension assets by walking up from the runtime directory and adding a second runtime-checked fallback for `dist/` layouts. - Adds a new unit test that simulates the “flat dist directory” bundled layout (`root/dist`) and asserts the resolver returns the package-root `assets/chrome-extension`. - Keeps existing behavior for the final default path so the caller’s error message remains unchanged when no manifest is found. <h3>Confidence Score: 3/5</h3> - Logic change is localized, but the accompanying tests contain at least one runtime error and should be fixed before merge. - The resolver change is straightforward and low blast-radius, but `src/cli/browser-cli-extension.test.ts` currently calls `vi.resetModules()` which is undefined in this repo’s Vitest environment, causing test failures. Fixing the test should bring confidence back up; no other definite functional regressions were found in the changed resolver logic. - src/cli/browser-cli-extension.test.ts <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs