parcel-bundler/parcel · error · Error

PostCSS config must have plugins

Error message

PostCSS config must have plugins

What it means

Thrown by @parcel/transformer-postcss's config loader when the config object exists but contents.plugins is null, not an object, or is an empty object/array. PostCSS without plugins is meaningless (Parcel already does default transpilation), so the loader refuses to run an empty PostCSS config. Distinct from 135 which fires first for non-object top-level values.

Source

Thrown at packages/transformers/postcss/src/loadConfig.js:204

    if (isDynamic) {
      // We have to invalidate on startup in case the config is non-deterministic,
      // e.g. using unknown environment variables, reading from the filesystem, etc.
      logger.warn({
        message:
          'WARNING: Using a JavaScript PostCSS config file means losing out on caching features of Parcel. Use a .postcssrc(.json) file whenever possible.',
      });
    }

    if (typeof contents !== 'object') {
      throw new Error('PostCSS config should be an object.');
    }

    if (
      contents.plugins == null ||
      typeof contents.plugins !== 'object' ||
      Object.keys(contents.plugins).length === 0
    ) {
      throw new Error('PostCSS config must have plugins');
    }
  }

  return configHydrator(
    contents,
    config,
    configFile?.filePath,
    options,
    logger,
  );
}

View on GitHub (pinned to 59484858a1)

Solutions

  1. Add at least one PostCSS plugin to the config (e.g. tailwindcss, postcss-preset-env, cssnano).
  2. If you do not need PostCSS plugins, delete the config file entirely — Parcel's default CSS pipeline already handles autoprefixing/transpilation.
  3. If only `postcss-modules` is used, set it under the `postcss-modules` key (the loader special-cases it before this check).

Example fix

// before: .postcssrc
{
  "plugins": {}
}
// after (option a): add a plugin
{
  "plugins": {
    "tailwindcss": {}
  }
}
// after (option b): delete .postcssrc and rely on Parcel defaults
Defensive patterns

Strategy: validation

Validate before calling

function assertPostCSSPlugins(contents) {
  if (!contents.plugins || typeof contents.plugins !== 'object' || Object.keys(contents.plugins).length === 0) {
    throw new Error('PostCSS config needs at least one plugin — or delete the config to use Parcel defaults');
  }
}

Type guard

function hasPostCSSPlugins(contents) {
  return Boolean(contents?.plugins) && typeof contents.plugins === 'object' && Object.keys(contents.plugins).length > 0;
}

Prevention

When it happens

Trigger: A PostCSS config like `{ plugins: {} }`, `{ plugins: [] }`, or `{ }` (plugins key absent). The check is `contents.plugins == null || typeof contents.plugins !== 'object' || Object.keys(contents.plugins).length === 0`.

Common situations: Starting from a template and forgetting to fill in plugins; intentionally creating an empty config; copy-paste that drops the plugins block; using a JS config whose plugins assignment was commented out.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/3e70d40d40378d96. Report an issue: GitHub.