facebook/docusaurus · error · Error
Wrong icon: ${icon}
Error message
Wrong icon: ${icon} What it means
Thrown by the IdealImage plugin's icon-state switch when it receives an `icon` value that is not one of the handled cases ('loading', 'loaded', 'error', '404'). The switch is meant to be exhaustive over the component's internal UI states, so reaching `default` indicates either an internal logic bug or a corrupted state machine. This is a defensive exhaustiveness guard, not a user-facing validation.
Source
Thrown at packages/docusaurus-plugin-ideal-image/src/theme/IdealImage/index.tsx:79
description: 'When the user is viewing an offline document',
});
case 'error': {
const {loadInfo} = state;
if (loadInfo === 404) {
return translate({
id: 'theme.IdealImageMessage.404error',
message: '404. Image not found',
description: 'When the image is not found',
});
}
return translate({
id: 'theme.IdealImageMessage.error',
message: 'Error. Click to reload',
description: 'When the image fails to load for unknown error',
});
}
default:
throw new Error(`Wrong icon: ${icon}`);
}
}
export default function IdealImage(props: Props): ReactNode {
const {img, ...propsRest} = props;
// In dev env just use regular img with original file
if (typeof img === 'string' || 'default' in img) {
return (
// eslint-disable-next-line jsx-a11y/alt-text
<img src={typeof img === 'string' ? img : img.default} {...propsRest} />
);
}
return (
<ReactIdealImage
{...propsRest}
height={img.src.height ?? 100}View on GitHub (pinned to 3f483e80e3)
Solutions
- Inspect the thrown `icon` value in the error message; it is almost always a typo or a new state name your swizzled copy does not know about.
- If you swizzled `theme/IdealImage`, re-run the swizzle diff against the upstream version and add the missing case to the switch.
- If the value comes from your own wrapper, ensure you only pass one of the documented statuses ('loading', 'loaded', 'error', '404').
- Avoid casting the icon to `any`; let TypeScript narrow it so the compiler flags missing cases.
Example fix
// before
function getStatusMessage(icon: string) {
switch (icon) {
case 'loading': return translate({...});
// ... missing 'loaded' case
default: throw new Error(`Wrong icon: ${icon}`);
}
}
// after
type IdealImageIcon = 'loading' | 'loaded' | 'error' | '404';
function getStatusMessage(icon: IdealImageIcon) {
switch (icon) {
case 'loading': return translate({...});
case 'loaded': return translate({...});
case 'error': return translate({...});
case '404': return translate({...});
default: { const _: never = icon; throw new Error(`Wrong icon: ${icon}`); }
}
} Defensive patterns
Strategy: type-guard
Validate before calling
const KNOWN_ICONS = new Set(['loading','loaded','error','404']);
function assertIcon(icon: string): void {
if (!KNOWN_ICONS.has(icon)) {
throw new TypeError(`Unsupported icon: ${icon}. Expected one of ${[...KNOWN_ICONS].join(', ')}`);
}
} Type guard
type IdealImageIcon = 'loading' | 'loaded' | 'error' | '404';
function isIdealImageIcon(v: unknown): v is IdealImageIcon {
return typeof v === 'string' && ['loading','loaded','error','404'].includes(v);
} Prevention
- Type the icon parameter as a literal union, not `string`, so TS catches missing cases.
- Use a `never`-narrowed default branch to get compile-time exhaustiveness checks.
- Re-swizzle against upstream after upgrading the ideal-image plugin.
When it happens
Trigger: The IdealImage component derives an `icon` string from its loading lifecycle. If a caller of the internal ` IdealImageMessage` / status helper passes a status string outside the known set, or if a future refactor adds a new state without extending the switch, the default branch fires.
Common situations: Swizzling `@theme/IdealImage` and passing a custom status string into the message helper; upgrading `@docusaurus/plugin-ideal-image` to a version whose lifecycle emits a new state while a stale swizzled component still has the old switch; type-system bypass (any-cast) hiding an unknown value at compile time.
Related errors
- unexpected color mode ${colorMode}
- unknown item type ${JSON.stringify(item)}
- Docusaurus could not load module at path path=${modulePath}
- Docusaurus plugin global data not found for "${pluginName}"
- Docusaurus plugin global data not found for "${pluginName}"
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/d440bdc0e71d4e7f.
Report an issue: GitHub.