gohugoio/hugo · error
failed to decode options: %s
Error message
failed to decode options: %s
What it means
Thrown by images.Dither when mapstructure.WeakDecode fails to decode the options argument into the dither options struct (filters.go:217-220). This happens when the options map contains fields of incompatible types that cannot be weakly coerced.
Source
Thrown at resources/images/filters.go:219
}
// Dither creates a filter that dithers an image.
func (*Filters) Dither(options ...any) gift.Filter {
ditherOptions := struct {
Colors []any
Method string
Serpentine bool
Strength float32
}{
Method: "floydsteinberg",
Serpentine: true,
Strength: 1.0,
}
if len(options) != 0 {
err := mapstructure.WeakDecode(options[0], &ditherOptions)
if err != nil {
panic(fmt.Sprintf("failed to decode options: %s", err))
}
}
if len(ditherOptions.Colors) == 0 {
ditherOptions.Colors = []any{"000000ff", "ffffffff"}
}
if len(ditherOptions.Colors) < 2 {
panic("palette must have at least two colors")
}
var palette []color.Color
for _, c := range ditherOptions.Colors {
cc, ok, err := toColorGo(c)
if !ok || err != nil {
panic(fmt.Sprintf("%q is an invalid color: specify RGB or RGBA using hexadecimal notation", c))
}
palette = append(palette, cc)View on GitHub (pinned to 52c9bd7908)
Solutions
- Provide a flat map with keys Colors ([]string), Method (string), Serpentine (bool), Strength (float).
- Ensure Colors is always a list even with one entry.
- Remove unrecognized/struct-valued keys.
Example fix
// before
{{ $filters = $filters | append (images.Dither (dict "Colors" "000000ff")) }}
// after
{{ $filters = $filters | append (images.Dither (dict "Colors" (slice "000000ff" "ffffffff"))) }} Defensive patterns
Strategy: validation
Validate before calling
{{ $opts := .opts }}
{{ if and (isset $opts "Colors") (not (reflect.IsSlice (index $opts "Colors"))) }}
{{ errorf "Dither Colors must be a slice" }}
{{ end }} Prevention
- Pass Dither options as a flat dict matching the documented keys/types.
- Keep Colors a slice of hex strings.
- Avoid nesting structs inside the options map.
When it happens
Trigger: Passing a Dither options map where Colors is not a list, Method/Serpentine/Strength are the wrong scalar types, or unknown nested structures. WeakDecode tolerates numeric/string coercion but rejects structural mismatches.
Common situations: Passing Colors as a single string instead of a slice; passing Strength as a map; or passing a struct where a map is expected.
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
- palette must have at least two colors
- %q is an invalid color: specify RGB or RGBA using hexadecima
- %q is an invalid dithering method: see documentation
- aligny must be one of top, center, bottom
- the padding filter requires between 1 and 5 arguments
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/a0d6c229f5d494a4.
Report an issue: GitHub.