{"record":{"id":"3e70d40d40378d96","repo":"parcel-bundler/parcel","slug":"postcss-config-must-have-plugins","errorCode":null,"errorMessage":"PostCSS config must have plugins","messagePattern":"PostCSS config must have plugins","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/transformers/postcss/src/loadConfig.js","lineNumber":204,"sourceCode":"    if (isDynamic) {\n      // We have to invalidate on startup in case the config is non-deterministic,\n      // e.g. using unknown environment variables, reading from the filesystem, etc.\n      logger.warn({\n        message:\n          'WARNING: Using a JavaScript PostCSS config file means losing out on caching features of Parcel. Use a .postcssrc(.json) file whenever possible.',\n      });\n    }\n\n    if (typeof contents !== 'object') {\n      throw new Error('PostCSS config should be an object.');\n    }\n\n    if (\n      contents.plugins == null ||\n      typeof contents.plugins !== 'object' ||\n      Object.keys(contents.plugins).length === 0\n    ) {\n      throw new Error('PostCSS config must have plugins');\n    }\n  }\n\n  return configHydrator(\n    contents,\n    config,\n    configFile?.filePath,\n    options,\n    logger,\n  );\n}\n","sourceCodeStart":186,"sourceCodeEnd":216,"githubUrl":"https://github.com/parcel-bundler/parcel/blob/59484858a1a0bcbb71f74088956bb437a2db6505/packages/transformers/postcss/src/loadConfig.js#L186-L216","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Add at least one PostCSS plugin to the config (e.g. tailwindcss, postcss-preset-env, cssnano).","If you do not need PostCSS plugins, delete the config file entirely — Parcel's default CSS pipeline already handles autoprefixing/transpilation.","If only `postcss-modules` is used, set it under the `postcss-modules` key (the loader special-cases it before this check)."],"exampleFix":"// before: .postcssrc\n{\n  \"plugins\": {}\n}\n// after (option a): add a plugin\n{\n  \"plugins\": {\n    \"tailwindcss\": {}\n  }\n}\n// after (option b): delete .postcssrc and rely on Parcel defaults","handlingStrategy":"validation","validationCode":"function assertPostCSSPlugins(contents) {\n  if (!contents.plugins || typeof contents.plugins !== 'object' || Object.keys(contents.plugins).length === 0) {\n    throw new Error('PostCSS config needs at least one plugin — or delete the config to use Parcel defaults');\n  }\n}","typeGuard":"function hasPostCSSPlugins(contents) {\n  return Boolean(contents?.plugins) && typeof contents.plugins === 'object' && Object.keys(contents.plugins).length > 0;\n}","tryCatchPattern":null,"preventionTips":["If you do not need PostCSS plugins, delete the config rather than leaving it empty.","Review PostCSS configs in PRs to ensure at least one plugin remains."],"tags":["postcss","config","css","transformer","validation"],"backgroundTag":null,"analyzedSha":"59484858a1a0bcbb71f74088956bb437a2db6505","analyzedAt":"2026-08-13T04:06:35.925Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}