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

  1. Add 'wasm-unsafe-eval' to the script-src (and worker-src if applicable) directive of the page's Content-Security-Policy
  2. Check console.warn output at script load for the underlying __impeccableInitError reason and fix that root cause first
  3. If you embed the detector in your own extension, ensure the page/extension CSP permits WebAssembly compilation
  4. 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

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


AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/5f7b739b7c128789. Report an issue: GitHub.