basecamp/trix · warning

TrustedTypes policy ' + policyName + ' could not be created.

Error message

TrustedTypes policy ' + policyName + ' could not be created.

What it means

DOMPurify, when running under browsers that enforce Trusted Types, tries to create a TrustedTypes policy (e.g. 'dompurify') to sign the HTML it returns. Policy creation is wrapped in try/catch; if it throws — most commonly because another DOMPurify instance or another script already created a policy with that exact name — the library logs this console.warn and returns null instead of throwing. Sanitization continues, but returned values will not be Trusted Types-wrapped, which can throw later if TT are enforced and unsanitized sinks are used.

Source

Thrown at action_text-trix/app/assets/javascripts/trix.js:2156

    const ATTR_NAME = 'data-tt-policy-suffix';
    if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
      suffix = purifyHostElement.getAttribute(ATTR_NAME);
    }
    const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
    try {
      return trustedTypes.createPolicy(policyName, {
        createHTML(html) {
          return html;
        },
        createScriptURL(scriptUrl) {
          return scriptUrl;
        }
      });
    } catch (_) {
      // Policy creation failed (most likely another DOMPurify script has
      // already run). Skip creating the policy, as this will only cause errors
      // if TT are enforced.
      console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
      return null;
    }
  };
  const _createHooksMap = function _createHooksMap() {
    return {
      afterSanitizeAttributes: [],
      afterSanitizeElements: [],
      afterSanitizeShadowDOM: [],
      beforeSanitizeAttributes: [],
      beforeSanitizeElements: [],
      beforeSanitizeShadowDOM: [],
      uponSanitizeAttribute: [],
      uponSanitizeElement: [],
      uponSanitizeShadowNode: []
    };
  };
  /**
   * Resolve a set-valued configuration option: a fresh set built from

View on GitHub (pinned to 4700401311)

Solutions

  1. Deduplicate: load only one copy of DOMPurify on the page (remove the separately bundled/CDN version if trix.js already includes it).
  2. Supply a unique DOMPurify instance name via SANITIZE_DOM... or create your own policy with a unique name and pass it as TRUSTED_TYPES_POLICY so DOMPurify does not need to create one.
  3. If the warning is expected (another policy is intentional), it is safe to ignore: sanitization still runs; only the TT wrapping is skipped.
  4. If TT are enforced and you need signed output, ensure the policy exists and RETURN_TRUSTED_TYPE is true with a working TRUSTED_TYPES_POLICY.

Example fix

// before: two DOMPurify copies on the page (CDN + bundled in trix)
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
// after: remove the standalone script and rely on the bundled copy,
// or pre-create a uniquely-named policy and pass it:
const policy = trustedTypes.createPolicy('myapp-dompurify', {
  createHTML: (s) => s,
  createScriptURL: (s) => s
});
DOMPurify.sanitize(dirty, { TRUSTED_TYPES_POLICY: policy, RETURN_TRUSTED_TYPE: true });
Defensive patterns

Strategy: fallback

Validate before calling

const ttAvailable = typeof window.trustedTypes !== 'undefined';
let policyExists = false;
try { trustedTypes.createPolicy('dompurify-probe', { createHTML: (s)=>s, createScriptURL: (s)=>s }); policyExists = true; } catch (e) { /* name taken or TT blocked */ }

Type guard

const canCreatePolicy = (w) => typeof w !== 'undefined' && !!w.trustedTypes && typeof w.trustedTypes.createPolicy === 'function';

Prevention

When it happens

Trigger: Trusted Types are enforced (or a CSP requires-trusted-types-for script is present) AND trustedTypes.createPolicy throws, typically because a policy named after the DOMPurify instance (e.g. 'dompurify') already exists without {createBehavior:'allow'}-style handling, or window.trustedTypes is present but createPolicy fails for the given name.

Common situations: Two copies of DOMPurify (or DOMPurify bundled both in trix.js and loaded separately) running on the same page; migrating an app to Trusted Types with an existing DOMPurify; a service worker / CSP requiring trusted types where a duplicate sanitizer already registered the policy name.

Related errors


AI-assisted analysis of basecamp/trix@4700401311 (2026-09-02). Data as JSON: /api/errors/e945444385e63341. Report an issue: GitHub.