Skip to content

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.

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.

Terminal window
nvm use 20
nvm alias default 20

Open 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.

When bash init.sh halts in the middle, the last line printed on screen narrows down where to look.

Where it stoppedWhere to look
At pnpm installThe “pnpm install fails with a permission error” entry above.
At pnpm run typecheckCopy 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 buildRead 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.

”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.

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.

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.

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.

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.

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.

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.

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.

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.

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).