Fix MV3 service worker crash by shimming ajv/ajv-formats#173
Open
insane66613 wants to merge 25 commits into
Open
Fix MV3 service worker crash by shimming ajv/ajv-formats#173insane66613 wants to merge 25 commits into
insane66613 wants to merge 25 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes Chrome Manifest V3 service worker crashes caused by CSP violations when transitive dependencies (via the MCP SDK) use ajv's runtime code generation with new Function() and eval. The solution implements build-time aliasing to replace ajv and ajv-formats with CSP-safe shims that provide permissive validation, along with a regression detection script.
Changes:
- Added three new Node.js utility scripts for environment management and unsafe-eval pattern detection
- Configured Vite to alias all ajv and ajv-formats imports to CSP-compliant shims for the background service worker
- Created three shim modules that provide minimal CSP-safe implementations of ajv, ajv-formats, and ajv codegen internals
- Removed missing icon-16.png reference from manifest to allow unpacked extension loading
- Added documentation explaining the MV3 CSP restrictions and validation script usage
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/set-global-env.mjs | New script to manage CLI-controlled environment variables with validation |
| scripts/scan-unsafe-eval.mjs | New regression detection script that scans dist output for unsafe-eval patterns |
| scripts/copy-env.mjs | New script to copy .example.env to .env if needed |
| package.json | Updated script commands to use new Node.js scripts and added scan:unsafe-eval command |
| chrome-extension/vite.config.mts | Added regex-based aliases to route ajv/ajv-formats imports to CSP-safe shims |
| chrome-extension/src/shims/ajv.ts | CSP-safe Ajv stub with permissive validation and method chaining support |
| chrome-extension/src/shims/ajv-formats.ts | No-op ajv-formats shim that returns the ajv instance unchanged |
| chrome-extension/src/shims/ajv-codegen.ts | Minimal Ajv codegen shim providing operators, template helpers, and KeywordCxt |
| chrome-extension/manifest.ts | Removed reference to non-existent icon-16.png file |
| README.md | Added documentation about MV3 CSP restrictions and how to run unsafe-eval scan |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Author
|
@copilot open a new pull request to apply changes based on the comments in this thread |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This was referenced Feb 12, 2026
Add workflow_dispatch trigger to build-zip.yml
Co-authored-by: insane66613 <8126035+insane66613@users.noreply.github.com>
chore: bump version to v0.6.1
[WIP] Fix Node.js engine mismatch in Release Extension workflow
Co-authored-by: insane66613 <8126035+insane66613@users.noreply.github.com>
…lease-workflow fix: use Node.js 22.12.0 in release workflow to satisfy engines.node requirement
Co-authored-by: insane66613 <8126035+insane66613@users.noreply.github.com>
…eObserver loop Co-authored-by: insane66613 <8126035+insane66613@users.noreply.github.com>
Fix: unload permission policy violation, SSE error mis-categorisation, and ResizeObserver loop
Fix missing icon-16.png causing Chrome extension load error
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes a Chrome MV3 runtime failure where the background service worker crashes due to CSP restrictions (unsafe-eval / new Function()), leaving “Available Tools” empty and causing handshake/message timeouts (see upstream issue #171).
Root cause
Some transitive dependencies pull in ajv / ajv-formats (including deep subpaths like ajv/dist/compile/codegen and ajv-formats/dist/formats). Ajv’s default schema compilation/codegen path uses new Function() and expects internal codegen symbols; MV3 service workers disallow this, which can crash the worker during initialization/tool schema validation.
Fix
Build-time “catch-all” aliasing + CSP-safe shims for the background bundle:
Alias all ajv-formats/* imports to a no-op shim.
Alias ajv/dist/compile/codegen to a small stub exporting the expected codegen surface (e.g. operators.LTE, _, str, KeywordCxt).
Alias all ajv/* imports to a CSP-safe Ajv stub that supports method chaining and permissive validation.
Also adds a regression check to prevent eval / new Function from reappearing in dist output.
Changes
vite.config.mts: regex aliases for ajv-formats/* and ajv/*, plus explicit alias for ajv/dist/compile/codegen
ajv.ts: chain-safe Ajv stub + Name and defensive codegen exports
ajv-codegen.ts: minimal Ajv codegen shim (operators/templates/KeywordCxt)
ajv-formats.ts: no-op ajv-formats shim
scan-unsafe-eval.mjs + package.json: scan:unsafe-eval script
README.md: short MV3 CSP note and how to run the scan
manifest.ts: remove missing icon-16.png reference to allow unpacked loading
How to test
Then load dist as unpacked and verify:
service worker registers and stays alive
tools list populates / connection succeeds (no CSP unsafe-eval errors)
Notes / tradeoff
The shim approach makes schema validation permissive in MV3 to keep the extension functional under CSP. A longer-term improvement would be switching to precompiled/standalone validators or otherwise removing runtime Ajv compilation from the service worker pat