{"record":{"id":"952cac276d6d9840","repo":"gohugoio/hugo","slug":"failed-to-compile-cache-buster-q-w","errorCode":null,"errorMessage":"failed to compile cache buster %q: %w","messagePattern":"failed to compile cache buster %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/commonConfig.go","lineNumber":172,"sourceCode":"\t\t}\n\t}\n\tif len(matchers) > 0 {\n\t\treturn (func(cacheKey string) bool {\n\t\t\tfor _, m := range matchers {\n\t\t\t\tif m(cacheKey) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}), nil\n\t}\n\treturn nil, nil\n}\n\nfunc (b *BuildConfig) CompileConfig(logger loggers.Logger) error {\n\tfor i, cb := range b.CacheBusters {\n\t\tif err := cb.CompileConfig(logger); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile cache buster %q: %w\", cb.Source, err)\n\t\t}\n\t\tb.CacheBusters[i] = cb\n\t}\n\treturn nil\n}\n\nfunc DecodeBuildConfig(cfg Provider) BuildConfig {\n\tm := cfg.GetStringMap(\"build\")\n\n\tb := defaultBuild.clone()\n\tif m == nil {\n\t\treturn b\n\t}\n\n\t// writeStats was a bool <= v0.115.0.\n\tif writeStats, ok := m[\"writestats\"]; ok {\n\t\tif bb, ok := writeStats.(bool); ok {\n\t\t\tm[\"buildstats\"] = BuildStats{Enable: bb}","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/config/commonConfig.go#L154-L190","documentation":"Emitted by BuildConfig.CompileConfig while iterating build.CacheBusters. For each cache buster it calls CacheBuster.CompileConfig (error 279's source), and wraps any failure with the buster's `source` string. So this is the per-buster wrapper inside the loop, whereas 279 is the inner compile of the source regexp itself.","triggerScenarios":"A `[build]` config with `cacheBusters` whose `source` is an invalid Go regexp; a typo like an unbalanced parenthesis or quantifier on nothing.","commonSituations":"Hand-writing cache busters for the dev server / fingerprinting and getting regexp syntax wrong; copying a glob pattern where a regexp is expected.","solutions":["Test the `source` value in a Go regexp tester or `go play`.","Remember Hugo cache busters use Go regexp syntax, not glob.","Remove the entry to confirm it is the culprit, then fix the pattern."],"exampleFix":"# before\n[build]\n[[build.cacheBusters]]\nsource = \"assets/(.*\"\ntarget = \"$1\"\n\n# after\n[build]\n[[build.cacheBusters]]\nsource = \"assets/(.*)\"\ntarget = \"$1\"","handlingStrategy":"validation","validationCode":"python3 - <<'PY'\nimport tomllib,re\ncfg=tomllib.loads(open('hugo.toml').read())\nfor cb in cfg.get('build',{}).get('cacheBusters',[]):\n    try: re.compile(cb['source'])\n    except re.error as e: print(f\"bad cacheBuster source {cb['source']!r}: {e}\")\nprint(\"cacheBusters ok\")\nPY","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Go RE2 regexp syntax for cacheBuster.source (not glob).","Test patterns in a Go regexp playground.","Escape regex metacharacters intended literally."],"tags":["config","build","regexp","cache"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}