gohugoio/hugo · error
permalinks: failed to decode target: %w
Error message
permalinks: failed to decode target: %w
What it means
Thrown by decodePermalinksSlice when mapstructure.WeakDecode of a rule's 'target' value into the PageMatcher struct fails. The wrapped error is the decode failure, so the target object's fields do not fit the PageMatcher schema (kind, path, language, environment, sites, etc.).
Source
Thrown at resources/page/permalinks.go:543
return decodePermalinksMap(v)
default:
if ms, err := hmaps.ToSliceStringMap(in); err == nil {
// New slice format.
return decodePermalinksSlice(ms)
}
return nil, fmt.Errorf("permalinks: unsupported config type %T", in)
}
}
func decodePermalinksSlice(ms []map[string]any) (PermalinksConfig, error) {
var configs PermalinksConfig
for _, m := range ms {
m = hmaps.CleanConfigStringMap(m)
var cfg PermalinkConfig
if targetVal, ok := m["target"]; ok {
if err := mapstructure.WeakDecode(targetVal, &cfg.Target); err != nil {
return nil, fmt.Errorf("permalinks: failed to decode target: %w", err)
}
cfg.Target.Kind = strings.ToLower(cfg.Target.Kind)
cfg.Target.Path = filepath.ToSlash(strings.ToLower(cfg.Target.Path))
}
if patternVal, ok := m["pattern"]; ok {
cfg.Pattern, ok = patternVal.(string)
if !ok {
return nil, fmt.Errorf("permalinks: pattern must be a string, got %T", patternVal)
}
} else {
return nil, fmt.Errorf("permalinks: missing pattern")
}
configs = append(configs, cfg)
}
return configs, nilView on GitHub (pinned to 52c9bd7908)
Solutions
- Make 'target' a map with string-valued fields (kind, path, language, environment, sites).
- Move a path-only target string into target = { path = "/posts/**" }.
- Check the wrapped error for the specific field that failed to decode.
Example fix
# before
[[permalinks]]
target = "/posts/**"
pattern = "/:year/:slug/"
# after
[[permalinks]]
target = { path = "/posts/**" }
pattern = "/:year/:slug/" Defensive patterns
Strategy: validation
Validate before calling
if tv, ok := m["target"]; ok {
if err := mapstructure.WeakDecode(tv, &page.PageMatcher{}); err != nil {
return fmt.Errorf("target shape invalid: %w", err)
}
} Try / catch
cfg, err := page.DecodePermalinksConfig(raw)
if err != nil { /* fix the offending target object */ } Prevention
- Write 'target' as a map with string-valued fields.
- Put path-only targets in target = { path = "..." }.
- Check the wrapped error for the failing field.
When it happens
Trigger: A list-format permalink rule whose 'target' has wrong field types, e.g. target = { kind = 123 } (int instead of string) or target = "/posts/**" (string instead of a map).
Common situations: Migrating from the map format to the new slice format and writing target as a plain string path, or typos in target field names/types.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- permalinks: unsupported config type %T
- permalinks: pattern must be a string, got %T
- permalink attribute not recognised
- failed to decode page map: %w
- failed to compile permalink target %d: %w
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/3310160661622736.
Report an issue: GitHub.