gohugoio/hugo · error

postcss config %q not found

Error message

postcss config %q not found

What it means

When running css.PostCSS, Hugo resolves the PostCSS config file: either the one the user names via the `config` option or an auto-discovered postcss.config.{js,mjs,cjs}. If the user explicitly specified a config path and BaseFs.ResolveJSConfigFile cannot find it (relative to the project/theme mounts), Hugo errors out rather than running postcss without it. Auto-discovery failures are silent; only an explicit, missing `config` fails.

Source

Thrown at resources/resource_transformers/cssjs/postcss.go:175

	if options.Config != "" {
		configFile = options.Config
	} else {
		for _, name := range []string{"postcss.config.js", "postcss.config.mjs", "postcss.config.cjs"} {
			configFile = t.rs.BaseFs.ResolveJSConfigFile(name)
			if configFile != "" {
				break
			}
		}
	}

	if configFile != "" {
		configFile = filepath.Clean(configFile)
		// We need an absolute filename to the config file.
		if !filepath.IsAbs(configFile) {
			configFile = t.rs.BaseFs.ResolveJSConfigFile(configFile)
			if configFile == "" && options.Config != "" {
				// Only fail if the user specified config file is not found.
				return fmt.Errorf("postcss config %q not found", options.Config)
			}
		}
	}

	var cmdArgs []any

	if configFile != "" {
		infol.Logf("use config file %q", configFile)
		cmdArgs = []any{"--config", configFile}
	}

	if optArgs := options.toArgs(); len(optArgs) > 0 {
		cmdArgs = append(cmdArgs, collections.StringSliceToInterfaceSlice(optArgs)...)
	}

	var errBuf bytes.Buffer

	stderr := io.MultiWriter(infow, &errBuf)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Verify the path passed in the `config` option exists relative to the project root (or a mounted theme/module dir).
  2. Place postcss.config.js in the project root and drop the `config` option to use auto-discovery.
  3. If the config comes from a module/theme, ensure it's included via module mounts.
  4. In CI, confirm the file is checked out and not gitignored.

Example fix

// before (template)
{{ $css := $styles | css.PostCSS (dict "config" "build/postcss.conf.js") }}
// after — file at project root, auto-discovered
{{ $css := $styles | css.PostCSS }}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(filepath.Join(projectDir, "postcss.config.js")); err != nil {
    // create it or drop the config option
}

Prevention

When it happens

Trigger: `{{ $css := $scss | css.PostCSS (dict "config" "path/to/postcss.config.js") }}` (or resources.PostCSS) where that path doesn't resolve within the project's mounted filesystems; absolute-looking paths outside the working dir; wrong filename or directory.

Common situations: Config file lives outside the Hugo working dir or isn't mounted (themes/modules without the file mounted); typo in the path; CI checkout missing the file; passing a directory instead of a file (the option may be a directory containing postcss.config.js — verify it exists).

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/b1047bb5c8f5cebf.json. Report an issue: GitHub ↗.