angular/components · error

The literal provided to MatIconRegistry was not trusted as s

Error message

The literal provided to MatIconRegistry was not trusted as safe HTML by Angular's DomSanitizer. Attempted literal was "${literal}".

What it means

MatIconRegistry.addSvgIconLiteralInNamespace sanitizes the supplied SafeHtml literal with DomSanitizer before registering it. If sanitization strips the content (returns empty/null), it means the literal was not explicitly trusted, and the registry throws this error instead of storing unsafe HTML.

Source

Thrown at src/material/icon/icon-registry.ts:222

  }

  /**
   * Registers an icon using an HTML string in the specified namespace.
   * @param namespace Namespace in which the icon should be registered.
   * @param iconName Name under which the icon should be registered.
   * @param literal SVG source of the icon.
   */
  addSvgIconLiteralInNamespace(
    namespace: string,
    iconName: string,
    literal: SafeHtml,
    options?: IconOptions,
  ): this {
    const cleanLiteral = this._sanitizer.sanitize(SecurityContext.HTML, literal);

    // TODO: add an ngDevMode check
    if (!cleanLiteral) {
      throw getMatIconFailedToSanitizeLiteralError(literal);
    }

    // Security: The literal is passed in as SafeHtml, and is thus trusted.
    const trustedLiteral = trustedHTMLFromString(cleanLiteral);
    return this._addSvgIconConfig(
      namespace,
      iconName,
      new SvgIconConfig('', trustedLiteral, options),
    );
  }

  /**
   * Registers an icon set by URL in the default namespace.
   * @param url
   */
  addSvgIconSet(url: SafeResourceUrl, options?: IconOptions): this {
    return this.addSvgIconSetInNamespace('', url, options);
  }

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Wrap the literal in trusted SafeHtml: this.sanitizer.bypassSecurityTrustHtml(svgString).
  2. Verify the SVG literal is well-formed HTML; the sanitizer returns empty for content it fully strips.
  3. Confirm the argument type is actually SafeHtml — a plain string should not be assignable; fix any loose typings.
  4. If sanitization keeps emptying valid SVG, register via addSvgIconLiteral with a static template literal so Angular trusts compile-time HTML.

Example fix

// before
registry.addSvgIconLiteral('fluffy', svgStringFromServer);
// after
registry.addSvgIconLiteral(
  'fluffy',
  this.sanitizer.bypassSecurityTrustHtml(svgStringFromServer),
);
Defensive patterns

Strategy: type-guard

Validate before calling

import { SafeHtml } from '@angular/platform-browser';
function isTrustedHtml(v: unknown): v is SafeHtml {
  return typeof v === 'object' && v !== null && 'changingThisBreaksApplicationSecurity' in v;
}
if (!isTrustedHtml(literal)) throw new Error('Wrap SVG string in bypassSecurityTrustHtml first');

Type guard

function isSafeHtml(v: unknown): v is SafeHtml {
  return !!v && typeof v === 'object' &&
    typeof (v as any).changingThisBreaksApplicationSecurity === 'string';
}

Try / catch

try {
  registry.addSvgIconLiteral(name, literal);
} catch (e) {
  if (e instanceof Error && e.message.includes('not trusted as safe HTML')) {
    console.error('Sanitize failed — check the SVG string is well-formed and trusted.');
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling registry.addSvgIconLiteral('icon', someHtmlString) with a plain string (bypassing sanitizer trust), or a SafeHtml built by bypassSecurityTrustHtml on content that Angular's sanitizer empties (e.g. non-HTML content or content stripped entirely).

Common situations: Passing raw SVG strings fetched from an API without wrapping in sanitizer.bypassSecurityTrustHtml; TypeScript types loosened to accept string as SafeHtml; literals constructed at runtime from untrusted sources being stripped to empty by the sanitizer.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/bd8a2abc9f18fcf7. Report an issue: GitHub.