gohugoio/hugo · error

failed to compile Glob

Error message

failed to compile Glob %q: %w

What it means

Raised by getGlob (segments.go:284) when hglob.GetGlob cannot compile a glob pattern from a segments config matchers field (kind, path, output). Hugo uses gobwas/glob; invalid pattern syntax — unbalanced brackets, stray metacharacters — surfaces here with the offending pattern quoted.

Solutions

  1. Open the wrapped error to see the glob parse detail, then fix the pattern (close brackets, escape special chars).
  2. Use simple wildcard patterns (`posts/*`, `**/*.md`) that gobwas/glob accepts.
  3. Test the pattern in isolation with gobwas/glob if unsure.

Example fix

# before
[segments]
  [segments.posts]
    [[segments.posts.includes]]
      path = ["posts[abc"]

# after
      path = ["posts/*"]
Defensive patterns

Strategy: validation

Validate before calling

# Sanity-check glob patterns in segments config (simple smoke test).
python3 - <<'PY'
import re,sys
txt=open('hugo.toml').read()
for m in re.finditer(r'path\s*=\s*\[([^\]]+)\]',txt):
    for pat in re.findall(r'"([^"]+)"',m.group(1)):
        if '[' in pat and pat.count('[')!=pat.count(']'):
            print('unbalanced glob:',pat)
PY

Prevention

When it happens

Trigger: A `[segments]` config entry whose `includes`/`excludes` lists contain a malformed glob: `[abc`, `**{`, unescaped special chars; patterns copied from a different glob dialect (e.g. gitignore) that gobwas/glob rejects.

Common situations: Writing segment filters for segmented builds with hand-crafted patterns; migrating glob syntax from another tool; negation prefix (`!`) applied to a pattern that itself is invalid.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/9d2710e152726e71. Report an issue: GitHub.

Appendix: source

Thrown at hugolib/segments/segments.go:284

// SegmentMatcherFields holds string slices of ordered filters for segment matching.
// The Glob patterns can be negated by prefixing with "! ".
// The first match wins (either include or exclude).
type SegmentMatcherFields struct {
	Kind   []string
	Path   []string
	Output []string
	Lang   string            // Deprecated: use Sites.Matrix instead.
	Sites  sitesmatrix.Sites // Note that we only use Sites.Matrix for now.
}

func getGlob(s string) (glob.Glob, error) {
	if s == "" {
		return nil, nil
	}
	g, err := hglob.GetGlob(s)
	if err != nil {
		return nil, fmt.Errorf("failed to compile Glob %q: %w", s, err)
	}
	return g, nil
}

func DecodeSegments(in map[string]any, segmentsToRender []string, logger loggers.Logger) (*config.ConfigNamespace[map[string]SegmentConfig, *Segments], error) {
	buildConfig := func(in any) (*Segments, any, error) {
		m, err := hmaps.ToStringMapE(in)
		if err != nil {
			return nil, nil, err
		}
		if m == nil {
			m = map[string]any{}
		}
		m = hmaps.CleanConfigStringMap(m)

		var segmentCfg map[string]SegmentConfig
		if err := mapstructure.WeakDecode(m, &segmentCfg); err != nil {
			return nil, nil, err

View on GitHub (pinned to 52c9bd7908)