gohugoio/hugo · error
failed to compile cache buster target %q: %w
Error message
failed to compile cache buster target %q: %w
What it means
Raised inside the compiled cache-buster matcher when the `target` pattern — after substituting `$1`, `$2`... capture groups from the source match — fails regexp.Compile. Unlike the source pattern, the target is compiled lazily per match because it depends on the matched groups, so this error can appear mid-build when a matching file changes, not at config load.
Source
Thrown at config/commonConfig.go:436
m := sourceRe.FindStringSubmatch(s)
matchString := "no match"
match := m != nil
if match {
matchString = "match!"
}
debugl.Logf("Matching %q with source %q: %s", s, source, matchString)
if !match {
return nil
}
groups := m[1:]
currentTarget := target
// Replace $1, $2 etc. in target.
for i, g := range groups {
currentTarget = strings.ReplaceAll(target, fmt.Sprintf("$%d", i+1), g)
}
targetRe, err := regexp.Compile(currentTarget)
if err != nil {
compileErr = fmt.Errorf("failed to compile cache buster target %q: %w", currentTarget, err)
return nil
}
return func(ss string) bool {
match := targetRe.MatchString(ss)
matchString := "no match"
if match {
matchString = "match!"
}
logger.Debugf("Matching %q with target %q: %s", ss, currentTarget, matchString)
return match
}
}
return compileErr
}
func (r Redirect) IsZero() bool {
return r.From == "" && r.FromRe == ""View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Fix the `target` regexp quoted in the error (the message shows the post-substitution pattern) so it compiles as RE2.
- If captured groups can contain regexp metacharacters, tighten the source capture group (e.g. `([\w-]+)`) so substituted values are regexp-safe.
- Test by touching a file matching the source pattern under `hugo server` and confirming the rebuild succeeds.
Example fix
# before (hugo.toml) [[build.cachebusters]] source = 'assets/js/(.*)\.js$' target = '$1\.(js' # after [[build.cachebusters]] source = 'assets/js/([\w-]+)\.js$' target = '$1\.js'
Defensive patterns
Strategy: validation
Validate before calling
for _, cb := range cfg.Build.CacheBusters {
if cb.Target != "" {
if _, err := regexp.Compile(cb.Target); err != nil {
return fmt.Errorf("build.cachebusters target %q: %w", cb.Target, err)
}
}
} Try / catch
if err := buildCfg.CompileConfig(logger); err != nil {
// "failed to compile cache buster target" — the 'target' regexp (possibly built from $1 capture substitution) is invalid
return err
} Prevention
- `target` is also a regexp, and Hugo substitutes capture groups from `source` into it — a `$1` that expands to regexp metacharacters can break compilation
- Keep capture groups in `source` matching only safe token characters (e.g. `([\w-]+)`) when referenced in `target`
- Test source+target as a pair against real file paths, not in isolation
When it happens
Trigger: A `[[build.cachebusters]]` `target` that is invalid RE2 on its own (e.g. unclosed group), or that becomes invalid after group substitution — e.g. the source captures a path fragment containing regexp metacharacters like `(` or `[`, and the substituted `$1` yields a broken pattern.
Common situations: Filenames or asset paths containing regexp special characters flowing into `$1` substitution; hand-written target regexps with typos that only surface when the source first matches during `hugo server` watch rebuilds; confusion that target is a regexp, not a literal replacement string.
Related errors
- failed to compile cache buster %q: %w
- failed to compile cache buster source %q: %w
- failed to compile Redirect regexp %q: %w
- failed to compile whitelist pattern %q: %w
- no modules loaded (need at least the main module)
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/a52d9d52c5927b35.json.
Report an issue: GitHub ↗.