mui/material-ui · error · Error
status ${response.status}
Error message
status ${response.status} What it means
download.mjs fetches each Material Icon variant from fonts.gstatic.com (e.g. https://fonts.gstatic.com/s/i/materialicons/<name>/v<version>/24px.svg). If the response status is not 200, it throws `status <code>` with no body context. This is a network/upstream guard so a partial icon set does not silently get written as an error-page SVG.
Source
Thrown at packages/mui-icons-material/scripts/download.mjs:163
* @param {string[]} icon.tags - The tags associated with the icon.
* @param {number[]} icon.sizes_px - The available sizes of the icon in pixels.
* @returns {Promise<void[]>} A promise that resolves when all icons are downloaded and saved.
*/
function downloadIcon(icon) {
console.log(`downloadIcon ${icon.index}: ${icon.name}`);
return Promise.all(
Object.keys(themeMap).map(async (theme) => {
const formattedTheme = themeMap[theme].split('_').join('');
const family = familyMap[theme];
if (icon.unsupported_families.includes(family)) {
return;
}
const response = await fetch(
`https://fonts.gstatic.com/s/i/materialicons${formattedTheme}/${icon.name}/v${icon.version}/24px.svg`,
);
if (response.status !== 200) {
throw new Error(`status ${response.status}`);
}
const SVG = await response.text();
await fs.writeFile(
path.join(
currentDirectory,
`../material-icons/${icon.name}${themeFileMap[theme]}_24px.svg`,
),
overrides.get(`${icon.name}${themeFileMap[theme]}`) || SVG,
);
}),
);
}
async function run() {
try {
const argv = yargs(process.argv.slice(2))
.usage('Download the SVG from material.io/resources/icons')
.describe('start-after', 'Resume at the following index').argv;View on GitHub (pinned to bdc96df2cb)
Solutions
- Retry the download script — most 5xx/429 responses are transient.
- If a specific icon 404s, refresh the icon metadata (codepoints/version manifest) so the version number is current.
- If behind a proxy, set HTTPS_PROXY and ensure the proxy permits fonts.gstatic.com.
- Skip unsupported families (the code already does) and confirm the icon name is spelled exactly as in the manifest.
Example fix
// before
const response = await fetch(url);
if (response.status !== 200) throw new Error(`status ${response.status}`);
// after — surface the failing URL/icon for diagnosis
if (response.status !== 200) throw new Error(`status ${response.status} for ${icon.name} (${url})`); Defensive patterns
Strategy: retry
Try / catch
async function fetchWithRetry(url, { retries = 3, backoff = 1000 } = {}) {
for (let attempt = 0; ; attempt++) {
const res = await fetch(url);
if (res.status === 200) return res;
if (res.status >= 500 && attempt < retries) { await new Promise(r => setTimeout(r, backoff * (attempt + 1))); continue; }
throw new Error(`status ${res.status} for ${url}`);
}
} Prevention
- Refresh the icon metadata manifest before bulk downloads so version numbers are current.
- Run downloads with a retry/backoff wrapper around fetch.
- Run icon downloads from a network that allows fonts.gstatic.com (no restrictive proxy).
When it happens
Trigger: Running the icon download script when an icon version is wrong (404), gstatic rate-limits or has an outage (429/5xx), or network/proxy returns a non-200 (captive portal, corporate proxy block).
Common situations: Material Icons metadata lists a version that does not exist on gstatic; transient gstatic errors; CI behind a restrictive proxy; outdated icon metadata cache.
Related errors
- Expected a single child of the root
- Expected an svg element as the root child
- renameFilter must be a function
- Duplicated icons in legacy folder. Either \n1. Remove these
- Failed to open in MUI Chat
AI-assisted analysis of mui/material-ui@bdc96df2cb (2026-08-12).
Data as JSON: /api/errors/a978457dfc356c62.
Report an issue: GitHub.