emberjs/ember.js · error · Error

Cannot create a ${tag} inside an SVG context

Error message

Cannot create a ${tag} inside an SVG context

What it means

When creating an element inside an SVG or MathML context, the HTML parser spec forbids certain HTML-only tags (the BLACKLIST_TABLE, e.g. <div>, <p>, <input>). Glimmer's createElement enforces this and throws instead of producing invalid DOM. It exists to prevent malformed trees when Glimmer renders an element that cannot legally be a child of an SVG/MathML subtree.

Source

Thrown at packages/@glimmer/runtime/lib/dom/operations.ts:68

      isElementInMathMlNamespace: boolean,
      ns: Namespace;

    if (context) {
      isElementInSVGNamespace = context.namespaceURI === NS_SVG || tag === 'svg';
      isElementInMathMlNamespace = context.namespaceURI === NS_MATHML || tag === 'math';
      isHTMLIntegrationPoint = !!(SVG_INTEGRATION_POINTS as Dict<number>)[context.tagName];
    } else {
      isElementInSVGNamespace = tag === 'svg';
      isElementInMathMlNamespace = tag === 'math';
      isHTMLIntegrationPoint = false;
    }

    if ((isElementInMathMlNamespace || isElementInSVGNamespace) && !isHTMLIntegrationPoint) {
      // FIXME: This does not properly handle <font> with color, face, or
      // size attributes, which is also disallowed by the spec. We should fix
      // this.
      if (BLACKLIST_TABLE[tag]) {
        throw new Error(`Cannot create a ${tag} inside an SVG context`);
      }
      if (isElementInMathMlNamespace) {
        ns = NS_MATHML;
      } else {
        ns = NS_SVG;
      }

      return this.document.createElementNS(ns, tag);
    } else {
      return this.document.createElement(tag);
    }
  }

  insertBefore(parent: SimpleElement, node: SimpleNode, reference: Nullable<SimpleNode>) {
    parent.insertBefore(node, reference);
  }

  insertHTMLBefore(parent: SimpleElement, nextSibling: Nullable<SimpleNode>, html: string): Bounds {

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Move the HTML element out of the SVG/MathML subtree in the template
  2. Wrap HTML content inside <foreignObject> within the SVG, which is an HTML integration point
  3. If the tag is dynamic, guard it so an HTML tag is never used in SVG context
  4. Fix the SVG markup so the offending element is a valid SVG child (e.g. use SVG equivalents like <text> instead of <div>)

Example fix

// before
<svg><div>hi</div></svg>
// after
<svg><foreignObject><div>hi</div></foreignObject></svg>
Defensive patterns

Strategy: validation

Validate before calling

const SVG_BLACKLIST = new Set(['div','p','span','input','table','ul','li','h1','h2','h3','button','form']);
if (inSvgContext && SVG_BLACKLIST.has(tag)) {
  throw new Error(`Tag <${tag}> cannot be created inside an SVG context`);
}

Type guard

function isSvgSafeTag(tag: string, inSvgContext: boolean): boolean {
  return !inSvgContext || !SVG_BLACKLIST.has(tag);
}

Prevention

When it happens

Trigger: Calling createElement(tag) while the current insertion point is inside an <svg> or <math> subtree (not an HTML integration point like <foreignObject>) and tag is in the blacklist table (e.g. div, span, input, p).

Common situations: Templates that put HTML tags inside an <svg> element (outside foreignObject); dynamic tag names ({{#let (someTag)}}<this.tag>) resolving to an HTML tag under SVG; programmatic DOM building with DOMTreeConstruction into SVG nodes.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/8025f95674f4a7cc. Report an issue: GitHub.