gohugoio/hugo · error

%q is an invalid color: specify RGB or RGBA using hexadecima

Error message

%q is an invalid color: specify RGB or RGBA using hexadecimal notation

What it means

Thrown by images.Dither when a palette color fails to parse via toColorGo (filters.go:232-236) — either it is not convertible to a string or it is a malformed hex value. The offending value is printed (%q).

Source

Thrown at resources/images/filters.go:235

		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)
	}

	d := dither.NewDitherer(palette)
	if method, ok := ditherMethodsErrorDiffusion[strings.ToLower(ditherOptions.Method)]; ok {
		d.Matrix = dither.ErrorDiffusionStrength(method, ditherOptions.Strength)
		d.Serpentine = ditherOptions.Serpentine
	} else if method, ok := ditherMethodsOrdered[strings.ToLower(ditherOptions.Method)]; ok {
		d.Mapper = dither.PixelMapperFromMatrix(method, ditherOptions.Strength)
	} else {
		panic(fmt.Sprintf("%q is an invalid dithering method: see documentation", ditherOptions.Method))
	}

	return filter{
		Options: newFilterOpts(ditherOptions),
		Filter:  ditherFilter{ditherer: d},
	}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Express every palette color as RGB/RGBA hex.
  2. Filter out invalid entries before passing the slice.
  3. Ensure each element is a string or an object implementing the colorGoProvider interface.

Example fix

// before
{{ $filters = $filters | append (images.Dither (dict "Colors" (slice "red" "white"))) }}
// after
{{ $filters = $filters | append (images.Dither (dict "Colors" (slice "ff0000ff" "ffffffff"))) }}
Defensive patterns

Strategy: validation

Validate before calling

{{ range $c := $colors }}
  {{ if not (findRE `^[0-9a-fA-F]{3,4}$|^[0-9a-fA-F]{6}$|^[0-9a-fA-F]{8}$` (trimPrefix "#" (printf "%v" $c))) }}
    {{ errorf "invalid palette color %q" $c }}
  {{ end }}
{{ end }}

Prevention

When it happens

Trigger: Any palette entry that is not valid hex (3/4/6/8 hex digits, optional #). Passing a named color, a malformed hex, or a non-string non-colorGoProvider value triggers it.

Common situations: Using CSS named colors ("red"), truncated hex, or accidentally including a number/object in the Colors slice.

Related errors


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