gohugoio/hugo · error · FileError
failed to resolve CSS @import
Error message
failed to resolve CSS @import "%s"; %s
What it means
Thrown by the CSS inline-import resolver when an @import statement in a CSS/SCSS file cannot be resolved to a resource in the import context or to a file on disk, and SkipInlineImportsNotFound is false. The message includes a hint to enable skipInlineImportsNotFound for node_modules-sourced imports.
Solutions
- Correct the @import path to point at an existing resource or file.
- If the import targets node_modules/vendor CSS that is already bundled by PostCSS, set options["skipInlineImportsNotFound"] = true so Hugo ignores unresolvable imports.
- Add the missing file to your assets directory and reference it by its assets-relative path.
Example fix
// before
{{ $css := resources.Get "css/main.css" | css.PostCSS }}
// main.css has @import "tailwind/dist.css" which is in node_modules
// after
{{ $css := resources.Get "css/main.css" | css.PostCSS (dict "skipInlineImportsNotFound" true) }} Defensive patterns
Strategy: validation
Validate before calling
// Walk CSS files and check each @import resolves to an asset file or resource.
import "regexp"
var importRe = regexp.MustCompile(`@import\s+["']([^"']+)["']`)
func unresolvedImports(css, assetsDir string) []string {
var missing []string
for _, m := range importRe.FindAllStringSubmatch(css, -1) {
p := filepath.Join(assetsDir, m[1])
if _, err := os.Stat(p); err != nil { missing = append(missing, m[1]) }
}
return missing
} Prevention
- Set skipInlineImportsNotFound=true when your CSS imports node_modules bundles already handled by PostCSS.
- Keep all @import targets under assets/ and reference them by assets-relative paths.
- Lint CSS @imports against the filesystem in CI before building.
When it happens
Trigger: A CSS file passed to css.PostCSS (with inlining) or the cssjs inline-imports transformer contains `@import "missing.css";` where missing.css is neither a Hugo resource nor a resolvable filesystem path. Reached when imp.importContent == nil after both importContext.Get and contentHash fail.
Common situations: Importing a CSS file that lives only in node_modules without enabling skipInlineImportsNotFound, a typo in an @import path, referencing a partial that was deleted, or moving SCSS files without updating @import URLs.
Related errors
- must not provide more arguments than resource object and…
- could not find in the import context
- {}
- postcss config not found
- : failed to transform ( )
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/8e6ede53fdb83973.
Report an issue: GitHub.
Appendix: source
Thrown at resources/resource_transformers/cssjs/inline_imports.go:163
if importContent == nil {
imp.dependencyManager.AddIdentity(identity.CleanStringIdentity(filename))
importContent, hash = imp.contentHash(filename)
nestedInPath = filepath.ToSlash(filename)
}
if importContent == nil {
if imp.opts.SkipInlineImportsNotFound {
trackLine(i, offset, line)
continue
}
pos := text.Position{
Filename: inPath,
LineNumber: offset + 1,
ColumnNumber: column + 1,
}
msgDetail := "if this import's source lives in node_modules, enable the skipInlineImportsNotFound option, see https://gohugo.io/functions/css/postcss/#skipinlineimportsnotfound"
return 0, "", herrors.NewFileErrorFromFileInPos(fmt.Errorf("failed to resolve CSS @import \"%s\"; %s", filename, msgDetail), pos, imp.fs, nil)
}
i--
if imp.contentSeen[hash] {
i++
// Just replace the line with an empty string.
replacements = append(replacements, []string{line, ""}...)
trackLine(i, offset, "IMPORT")
continue
}
imp.contentSeen[hash] = true
// Handle recursive imports.
l, nested, err := imp.importRecursive(i+lineNum, string(importContent), nestedInPath)
if err != nil {
return 0, "", errView on GitHub (pinned to 52c9bd7908)