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 fromView on GitHub (pinned to 4700401311)
Solutions
- Deduplicate: load only one copy of DOMPurify on the page (remove the separately bundled/CDN version if trix.js already includes it).
- 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.
- If the warning is expected (another policy is intentional), it is safe to ignore: sanitization still runs; only the TT wrapping is skipped.
- 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
- Ship exactly one copy of DOMPurify per page (audit bundles for duplicates).
- Pre-create your own uniquely-named policy and pass it via TRUSTED_TYPES_POLICY.
- Treat this console.warn as a smoke test when enabling Trusted Types in CSP.
- Test the app with require-trusted-types-for 'script' in a staging CSP before rollout.
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
- A configured TRUSTED_TYPES_POLICY callback (createHTML or cr
- TRUSTED_TYPES_POLICY configuration option must provide a "cr
- TRUSTED_TYPES_POLICY configuration option must provide a "cr
- a node selected for removal could not be detached from its t
- dirty is not a string, aborting
AI-assisted analysis of basecamp/trix@4700401311 (2026-09-02).
Data as JSON: /api/errors/e945444385e63341.
Report an issue: GitHub.