mermaid-js/mermaid · error

Invalid icon loader. Must have a "name" property with non-em

Error message

Invalid icon loader. Must have a "name" property with non-empty string value.

What it means

Thrown by registerIconPacks when an icon loader object in the passed array has no `name` property or an empty-string name. The name is used as the registry key (it overrides the iconify pack prefix), so every loader must declare one. This is a fail-fast guard before the loader/icons branches are even considered.

Source

Thrown at packages/mermaid/src/rendering-util/icons.ts:32

  name: string;
  icons: IconifyJSON;
}

export type IconLoader = AsyncIconLoader | SyncIconLoader;

export const unknownIcon: IconifyIcon = {
  body: '<g><rect width="80" height="80" style="fill: #087ebf; stroke-width: 0px;"/><text transform="translate(21.16 64.67)" style="fill: #fff; font-family: ArialMT, Arial; font-size: 67.75px;"><tspan x="0" y="0">?</tspan></text></g>',
  height: 80,
  width: 80,
};

const iconsStore = new Map<string, IconifyJSON>();
const loaderStore = new Map<string, AsyncIconLoader['loader']>();

export const registerIconPacks = (iconLoaders: IconLoader[]) => {
  for (const iconLoader of iconLoaders) {
    if (!iconLoader.name) {
      throw new Error(
        'Invalid icon loader. Must have a "name" property with non-empty string value.'
      );
    }
    log.debug('Registering icon pack:', iconLoader.name);
    if ('loader' in iconLoader) {
      loaderStore.set(iconLoader.name, iconLoader.loader);
    } else if ('icons' in iconLoader) {
      iconsStore.set(iconLoader.name, iconLoader.icons);
    } else {
      log.error('Invalid icon loader:', iconLoader);
      throw new Error('Invalid icon loader. Must have either "icons" or "loader" property.');
    }
  }
};

const getRegisteredIconData = async (iconName: string, fallbackPrefix?: string) => {
  const data = stringToIcon(iconName, true, fallbackPrefix !== undefined);
  if (!data) {

View on GitHub (pinned to d93e9c88c0)

Solutions

  1. Add a non-empty `name` string to every loader object passed to registerIconPacks; it becomes the prefix users reference in diagrams (e.g. name: 'logos').
  2. If using a static iconify JSON pack, set name to the pack's own prefix: name: icons.prefix.
  3. Type-check your array against the exported IconLoader (AsyncIconLoader | SyncIconLoader) union so the TS compiler rejects nameless objects before runtime.
  4. Log the offending element: the log.error call only fires for the icons/loader branch, so for the name guard inspect each entry manually before calling.

Example fix

// before
mermaid.registerIconPacks([
  { loader: () => import('@iconify-json/logos').then((m) => m.icons) },
]);
// after
mermaid.registerIconPacks([
  {
    name: 'logos',
    loader: () => import('@iconify-json/logos').then((m) => m.icons),
  },
]);
Defensive patterns

Strategy: validation

Validate before calling

function isValidIconLoader(x: unknown): x is { name: string } & Record<string, unknown> {
  return typeof x === 'object' && x !== null && typeof (x as any).name === 'string' && (x as any).name.length > 0;
}
const safe = iconLoaders.filter(isValidIconLoader);
if (safe.length !== iconLoaders.length) throw new Error('one or more icon loaders lack a non-empty name');
mermaid.registerIconPacks(safe);

Type guard

function isNamedIconLoader(x: unknown): x is { name: string } {
  return typeof x === 'object' && x !== null && typeof (x as any).name === 'string' && (x as any).name.trim() !== '';
}

Try / catch

try { mermaid.registerIconPacks(loaders); } catch (e) { console.error('icon pack registration failed:', e); throw e; }

Prevention

When it happens

Trigger: Calling mermaid.registerIconPacks([{ loader: () => import('@iconify-json/logos') }]) (object with only a `loader` key), or registerIconPacks([{ name: '', icons }]) (empty-string name), or registerIconPacks([{}]) (empty object). Any element where `!iconLoader.name` is truthy triggers it.

Common situations: Typo on the `name` field (e.g. `Name` or `packName`), destructuring a pack and forgetting to spread `name`, or building loader objects dynamically and skipping the name when a fetch/import succeeds. Also when copying docs examples and accidentally dropping the `name` line.

Related errors


AI-assisted analysis of mermaid-js/mermaid@d93e9c88c0 (2026-08-12). Data as JSON: /api/errors/a67927b351ac72fb. Report an issue: GitHub.