Troubleshooting
This page collects the spots people most often get stuck at. Find the entry that matches what you are seeing and follow the notes underneath. If nothing here matches, copy the error message verbatim into Claude Code and ask “how do I fix this?”. It is usually good at suggesting the next thing to try.
Stuck during environment setup
Section titled “Stuck during environment setup”Node will not install
Section titled “Node will not install”Usually this means nvm install 20 froze partway through, or failed outright.
On macOS or Linux, open a fresh terminal and run command -v nvm. If the output is empty, nvm itself installed but its loader was not added to your shell startup file (.zshrc or .bashrc). Paste the two lines the nvm install printout suggested (export NVM_DIR="$HOME/.nvm" ...) into that file by hand and open a new terminal.
On Windows, double-check that you actually finished the WSL2 install. The commands in this guide do not work in PowerShell — every step belongs in your Ubuntu shell on WSL2.
node --version prints something older than v20
Section titled “node --version prints something older than v20”This is what happens when more than one Node version is installed and the system default points at an older one.
nvm use 20nvm alias default 20Open a new terminal afterwards and run node --version again to confirm.
pnpm install fails with a permission error
Section titled “pnpm install fails with a permission error”If you see EACCES or permission denied, the global install location for npm is the most likely culprit. This base does not need any global install, so it is worth trying these in order before anything else.
- Do not retry with
sudo. That tends to compound the problem rather than fix it. - If
node_modules/already exists in the project folder from a previous attempt, delete it and try again:rm -rf node_modules pnpm-lock.yaml. - If the error sticks around, reinstall the nvm copy of Node:
nvm uninstall 20 && nvm install 20.
init.sh failed
Section titled “init.sh failed”When bash init.sh halts in the middle, the last line printed on screen narrows down where to look.
| Where it stopped | Where to look |
|---|---|
At pnpm install | The “pnpm install fails with a permission error” entry above. |
At pnpm run typecheck | Copy the type-error output and paste it into Claude Code. The cause is usually a path-alias mismatch in tsconfig.json or a dependency version mismatch. |
At pnpm run build | Read the build log all the way through. If you see CRXJS errors, the most common cause is a wrong entry-point path in manifest.config.ts. |
Chrome will not load the extension
Section titled “Chrome will not load the extension””Load unpacked” does not show my folder
Section titled “”Load unpacked” does not show my folder”You need to point at the dist/ folder on your machine. If you have not run a build yet, run pnpm run build first. If the folder is visible but greyed out, check whether manifest.json exists inside dist/. If it does not, the build did not complete successfully.
”Manifest file is missing or unreadable”
Section titled “”Manifest file is missing or unreadable””dist/manifest.json either was not generated or got malformed. Run pnpm run build again, and read the build log to see if any errors slipped past.
The extension loaded but the icon is missing
Section titled “The extension loaded but the icon is missing”Click the puzzle-piece icon in the top-right of Chrome to expand the extension list. Find your extension and click the pin icon — that pins it to the toolbar permanently.
The first run does nothing
Section titled “The first run does nothing”The sidepanel does not open
Section titled “The sidepanel does not open”First check that your Chrome version is 114 or newer (chrome://version). The sidepanel API was added in Chrome 114. If your version is fine and the panel still does not open, look at manifest.json and confirm sidePanel is in the permissions array. If it is missing, the trigger UI mode was not applied correctly.
”Analyze and send” prints nothing in the console
Section titled “”Analyze and send” prints nothing in the console”Start by checking that the backend mode in the options page (chrome://extensions → your extension → Details → Extension options) is set to console-log.
Then there is the question of which console you should be looking at, which trips a lot of people up the first time. The sidepanel’s own console is reachable by right-clicking inside the sidepanel and choosing “Inspect → Console”. The background service worker has a separate console — open chrome://extensions, click Details on your extension, and click the “Service Worker” link to pop it out. The analyzed payload normally lands in the background console.
Stuck on the backend connection
Section titled “Stuck on the backend connection”401 or 403 errors
Section titled “401 or 403 errors”For supabase-direct, copy the anon key again from Supabase’s Settings → API page (the anon public row). Never use the service_role key inside the extension — that key has full access to your data, and shipping it inside an extension is a security incident waiting to happen.
For server-relay, check the end of the token for trailing whitespace or stray newlines. Copy-paste into the options page is a very common source of that.
Data does not appear in Supabase
Section titled “Data does not appear in Supabase”Open the Table Editor and confirm page_contents is actually there. The table you created in the SQL Editor may have ended up in a different schema — verify it lives in public. Then go to Authentication → Policies and confirm the RLS policy you created allows INSERT. If both of those are correct, open the Network tab in DevTools and read the response body of the request to supabase.co. The reason the request was rejected is in there.
CORS errors (server-relay only)
Section titled “CORS errors (server-relay only)”Your server has to allow the extension’s origin. The extension’s origin is chrome-extension://<extension-id>, and the extension-id is shown on its card in chrome://extensions. Add that origin to your server’s Access-Control-Allow-Origin, or — if you are working under a private-distribution assumption — allow every chrome-extension:// origin.
Stuck on build or packaging
Section titled “Stuck on build or packaging”pnpm run package cannot produce the zip
Section titled “pnpm run package cannot produce the zip”pnpm run build has to finish cleanly first. If dist/ is missing or empty, package has nothing to wrap. Read the build log all the way through, and if errors show up, paste the message into Claude Code.
The dev server suddenly will not start
Section titled “The dev server suddenly will not start”When you run pnpm run dev, you may see a “port already in use” message. That happens when a previous dev server did not shut down. Open a new terminal and kill the process holding the port — something like lsof -ti:5173 | xargs kill works. The port number may not be 5173, so double-check what the message says.
Code changes are not reflected in the extension
Section titled “Code changes are not reflected in the extension”Two places to suspect. First, check that the dev server is still running. If pnpm run dev stopped, no new build is reaching the extension. Second, the background service worker reloads more slowly than other entry points — click the refresh icon on your extension card in chrome://extensions to force it.
Content script changes usually need a page reload to take effect. Press F5 in the same tab and the new content script will be re-injected.
Auto-disabled after a permission change
Section titled “Auto-disabled after a permission change”When Chrome detects that manifest permissions have changed, it temporarily disables the extension to re-request user consent. Look at your extension card in chrome://extensions — if the toggle is off, turn it back on. A prompt explaining the new permissions appears once; click through it and the extension resumes.
The extension ID changed unexpectedly
Section titled “The extension ID changed unexpectedly”This almost always means the .crx packing key (.pem) changed, or the extension was re-loaded as unpacked. An unpacked extension’s ID is derived from the folder path, so moving the folder produces a new ID. If you are on a self-hosted .crx distribution, revisit the “.pem key generation and storage” entry in 09-distribution.md. The ID stays stable only when the same key packs the same folder.
Anything else
Section titled “Anything else”If nothing on this page matches what you are seeing, two more things are worth trying.
First, copy the entire error message into Claude Code and ask “fix this for me”. It is usually good at suggesting a next step.
If that still does not get you unstuck, open a GitHub issue or post in your team’s Slack with three pieces of information together: where you got stuck (which file and which command), the full error message, and your environment (macOS / Linux / Windows, Node version, Chrome version).