pbakaus/impeccable · error · Error
[impeccable] detector core unavailable: ${reason} (a Content
Error message
[impeccable] detector core unavailable: ${reason} (a Content-Security-Policy without 'wasm-unsafe-eval' blocks WebAssembly) What it means
The impeccable detector core (a WebAssembly module) failed to initialize, most often because the page's Content-Security-Policy script-src lacks 'wasm-unsafe-eval', which Chrome requires for WASM instantiation. The bundle deliberately keeps the documented API surface (window.impeccableDetect, impeccableScan, etc.) as functions that throw this one clear error, instead of leaving them undefined or failing obscurely. A console.warn with the same message is emitted at load time.
Source
Thrown at browser-bundle/50-scan.js:21
// marshalling), and the extension-mode message loop of the standalone
// bundle. Ported from cli/engine/browser/injected/index.mjs Section 7; every
// rule decision is a call into the WASM core (`__impeccable.*`), the DOM
// reads it needs go through the probe, the overlay UI is 40-overlay.js and
// the visual-contrast sampling 35-visual.js.
const IS_BROWSER = typeof window !== 'undefined';
// ─── Section 7: Browser UI (IS_BROWSER only) ────────────────────────────────
if (IS_BROWSER && !__impeccable) {
// The core could not start (in practice: a Content-Security-Policy whose
// script-src lacks 'wasm-unsafe-eval'). Keep the API surface so callers get
// one clear error instead of "impeccableDetect is not a function".
const reason = __impeccableInitError && __impeccableInitError.message
? __impeccableInitError.message
: String(__impeccableInitError);
const message = `[impeccable] detector core unavailable: ${reason} (a Content-Security-Policy without 'wasm-unsafe-eval' blocks WebAssembly)`;
const fail = () => { throw new Error(message); };
const _myScript = document.currentScript;
const EXTENSION_MODE = (_myScript && _myScript.dataset.impeccableExtension === 'true')
|| document.documentElement.dataset.impeccableExtension === 'true';
console.warn(message);
window.impeccableDetect = fail;
window.impeccableDetectAsync = async () => fail();
window.impeccableScan = fail;
window.impeccableScanAsync = async () => fail();
window.impeccableMeasureHiddenText = fail;
window.impeccableCollectVisualContrastCandidates = fail;
window.impeccableAnalyzeVisualContrast = async () => fail();
window.impeccableGetLastVisualContrastAnalyses = () => [];
window.__impeccableCoreError = message;
if (EXTENSION_MODE) {
window.addEventListener('message', (e) => {
if (e.source !== window || !e.data || e.data.source !== 'impeccable-command') return;
if (e.data.action === 'scan') window.postMessage({ source: 'impeccable-error', message }, '*');
});View on GitHub (pinned to 2bc2879276)
Solutions
- Add 'wasm-unsafe-eval' to the script-src (and worker-src if applicable) directive of the page's Content-Security-Policy
- Check console.warn output at script load for the underlying __impeccableInitError reason and fix that root cause first
- If you embed the detector in your own extension, ensure the page/extension CSP permits WebAssembly compilation
- Verify the core .wasm asset is served from an allowed origin beside the script
Example fix
// before (meta tag) <meta http-equiv="Content-Security-Policy" content="script-src 'self'"> // after <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'wasm-unsafe-eval'">
Defensive patterns
Strategy: try-catch
Validate before calling
function detectorUsable() {
return typeof window.impeccableDetect === 'function' &&
!document.querySelector('meta[http-equiv="Content-Security-Policy"][content*:not(*wasm-unsafe-eval)]');
}
// simplest pre-check: verify CSP allows wasm
const csp = document.querySelector('meta[http-equiv="Content-Security-Policy"]')?.content || '';
const cspAllowsWasm = !csp || csp.includes('wasm-unsafe-eval'); Type guard
function hasDetector(w) { return typeof w.impeccableDetect === 'function' && typeof w.impeccableScan === 'function'; } Try / catch
try {
const findings = window.impeccableDetect();
} catch (e) {
if (String(e.message).includes('detector core unavailable')) {
console.warn('CSP blocks WASM; add wasm-unsafe-eval to script-src');
}
} Prevention
- Always include 'wasm-unsafe-eval' in CSP templates used with the detector
- Listen for the load-time console.warn before relying on the API
- Feature-check window.impeccableDetect is callable before calling it
- Test the detector behind your production CSP, not just locally
When it happens
Trigger: Any call to window.impeccableDetect, impeccableDetectAsync, impeccableScan, or impeccableScanAsync after the core's init threw (typically a CSP violation during WebAssembly.instantiate). The underlying reason string is embedded in the message.
Common situations: Embedding the detector script on a site with a strict CSP that was not updated for WASM; serving the detector from an extension page whose CSP differs; testing locally behind a security-hardened CSP template.
Related errors
- config.cspChecked, if present, must be a boolean
- the offscreen adapter is asynchronous
- [impeccable] the offscreen document has no live page; load a
- `WebAssembly.instantiateStreaming` failed because your serve
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/5f7b739b7c128789.
Report an issue: GitHub.