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
- Ensure the SVG source's single root element is <svg>...</svg>.
- Remove custom SVGO plugins that rename or unwrap the root svg element.
- 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
- Ensure every icon source's outermost element is <svg>.
- Avoid SVGO plugins that unwrap or rename the root svg.
- Add a pre-build lint that asserts the root tag name is svg.
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
- Expected a single child of the root
- renameFilter must be a function
- Duplicated icons in legacy folder. Either \n1. Remove these
- docs-infra: The title "${title}" is too long (${title.length
- docs-infra: Missing description in the page: ${location}\n
AI-assisted analysis of mui/material-ui@bdc96df2cb (2026-08-12).
Data as JSON: /api/errors/3d848776424a20c6.
Report an issue: GitHub.