mui/material-ui · error · Error

Expected an svg element as the root child

Error message

Expected an svg element as the root child

What it means

The same SVGO plugin asserts that the single root child is an <svg> element (type 'element' and name 'svg'). If the root child is a different element (e.g. <g>, <symbol>, or a non-element node like a text/comment that survived optimisation), the icon builder throws because the React template expects to wrap an <svg>.

Source

Thrown at packages/mui-icons-material/builder.mjs:151

    ],
  });

  // True if the svg has multiple children
  let childrenAsArray = false;
  const jsxResult = svgo.optimize(result.data, {
    plugins: [
      {
        name: 'svgAsReactFragment',
        fn: () => {
          return {
            root: {
              enter(root) {
                const [svg, ...rootChildren] = root.children;
                if (rootChildren.length > 0) {
                  throw new Error('Expected a single child of the root');
                }
                if (svg.type !== 'element' || svg.name !== 'svg') {
                  throw new Error('Expected an svg element as the root child');
                }

                if (svg.children.length > 1) {
                  childrenAsArray = true;
                  svg.children.forEach((svgChild, index) => {
                    svgChild.attributes.key = index;
                    // Original name will be restored later
                    // We just need a mechanism to convert the resulting
                    // svg string into an array of JSX elements
                    svgChild.name = `SVGChild:${svgChild.name}`;
                  });
                }

                root.children = svg.children;
              },
            },
          };
        },

View on GitHub (pinned to bdc96df2cb)

Solutions

  1. Ensure the SVG source's single root element is <svg>...</svg>.
  2. Remove custom SVGO plugins that rename or unwrap the root svg element.
  3. Re-export the icon from a vector tool with 'SVG document' output rather than a fragment.

Example fix

<!-- before -->
<g><path d="..."/></g>
<!-- after -->
<svg xmlns="http://www.w3.org/2000/svg"><g><path d="..."/></g></svg>
Defensive patterns

Strategy: validation

Validate before calling

function rootIsSvg(svgString) {
  const match = svgString.trim().match(/^<svg[\s>]/i);
  return !!match;
}
if (!rootIsSvg(source)) throw new Error('Expected <svg> as the root element');

Prevention

When it happens

Trigger: Feeding the builder an SVG whose outermost element is not <svg> (e.g. a bare <g> or <path>), or an SVG whose root <svg> was stripped/renamed by an SVGO plugin.

Common situations: Hand-authored icon fragment not wrapped in <svg>; SVGO plugin misconfiguration stripping the root; copied icon markup missing the outer svg tag.

Related errors


AI-assisted analysis of mui/material-ui@bdc96df2cb (2026-08-12). Data as JSON: /api/errors/3d848776424a20c6. Report an issue: GitHub.