angular/angular-cli · error · Error

Attempted to load invalid Postcss plugin: "${pluginName}"

Error message

Attempted to load invalid Postcss plugin: "${pluginName}"

What it means

When a custom PostCSS configuration file is present, the styles webpack config requires each configured plugin and validates it is a genuine PostCSS plugin (a function with `plugin.postcss === true`). This error is thrown when a resolved plugin module fails that check, so webpack refuses to build with an invalid plugin entry.

Source

Thrown at packages/angular_devkit/build_angular/src/tools/webpack/configs/styles.ts:93

      });
    },
  });

  const assetNameTemplate = assetNameTemplateFactory(hashFormat);

  const extraPostcssPlugins: import('postcss').Plugin[] = [];

  const searchDirectories = await generateSearchDirectories([projectRoot, root]);
  const postcssConfig = await loadPostcssConfiguration(searchDirectories);

  if (postcssConfig) {
    const postCssPluginRequire = createRequire(path.dirname(postcssConfig.configPath) + '/');

    for (const [pluginName, pluginOptions] of postcssConfig.config.plugins) {
      const pluginMod = postCssPluginRequire(pluginName);
      const plugin = pluginMod.__esModule ? pluginMod['default'] : pluginMod;
      if (typeof plugin !== 'function' || plugin.postcss !== true) {
        throw new Error(`Attempted to load invalid Postcss plugin: "${pluginName}"`);
      }

      extraPostcssPlugins.push(plugin(pluginOptions));
    }
  } else {
    // Attempt to setup Tailwind CSS
    // Only load Tailwind CSS plugin if configuration file was found.
    // This acts as a guard to ensure the project actually wants to use Tailwind CSS.
    // The package may be unknowningly present due to a third-party transitive package dependency.
    const tailwindConfigPath = findTailwindConfiguration(searchDirectories);
    if (tailwindConfigPath) {
      let tailwindPackagePath;
      try {
        tailwindPackagePath = require.resolve('tailwindcss', { paths: [root] });
      } catch {
        const relativeTailwindConfigPath = path.relative(root, tailwindConfigPath);
        logger.warn(
          `Tailwind CSS configuration file found (${relativeTailwindConfigPath})` +

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Fix the plugin name/path in your postcss config so it resolves to the intended PostCSS plugin package (install it if missing).
  2. Ensure the plugin is exported as a function with `postcss: true` (use `require('postcss-plugin')` not a wrapper object).
  3. For ES-module/default exports, make sure the default export is the plugin function.
  4. Remove invalid entries from the plugins map, or delete the postcss config to fall back to the built-in (Tailwind-aware) setup.

Example fix

// before: postcss.config.js
module.exports = { plugins: { 'autoprefixer': {}, 'some-random-pkg': {} } };
// after
module.exports = { plugins: { 'autoprefixer': {} } }; // only real PostCSS plugins
Defensive patterns

Strategy: validation

Validate before calling

const plugin = require(pluginName);
const fn = plugin.__esModule ? plugin.default : plugin;
if (typeof fn !== 'function' || fn.postcss !== true) {
  throw new Error(`${pluginName} is not a valid PostCSS plugin`);
}

Type guard

function isPostcssPlugin(mod: unknown): mod is ((...args: unknown[]) => unknown) & { postcss: true } {
  const m = mod as { __esModule?: boolean; default?: unknown };
  const plugin = (m && m.__esModule ? m.default : mod) as unknown;
  return typeof plugin === 'function' && (plugin as { postcss?: boolean }).postcss === true;
}

Prevention

When it happens

Trigger: Having a `postcss.config.js`/`.json` in the project whose `plugins` map contains a name that resolves to a module that is not a PostCSS plugin — e.g. a typo'd plugin name resolving to an unrelated package, a plugin exported as `{ default: fn }` where default is not a function, or an object-style plugin definition unsupported here.

Common situations: Listing a package that was never installed (name resolving to the wrong module or failing expectations); passing a plugin as a plain object instead of via a factory function; upgrading a PostCSS plugin whose export shape changed (no `postcss: true` marker); misconfigured custom PostCSS config path in angular.json.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/c4f283b81970fd3b. Report an issue: GitHub.