gohugoio/hugo · error

palette must have at least two colors

Error message

palette must have at least two colors

What it means

Thrown by images.Dither when the palette has fewer than two colors (filters.go:223-229). Note the filter seeds a default two-color palette when Colors is empty, so this only fires when exactly one color is supplied — dithering requires at least two to be meaningful.

Source

Thrown at resources/images/filters.go:228

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

	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 {

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Provide at least two palette colors.
  2. If you want defaults, omit Colors entirely rather than passing one value.
  3. Guard dynamic palette slices to ensure length >= 2.

Example fix

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

Strategy: validation

Validate before calling

{{ $colors := .colors | default (slice "000000ff" "ffffffff") }}
{{ if lt (len $colors) 2 }}{{ errorf "palette needs >= 2 colors" }}{{ end }}

Prevention

When it happens

Trigger: Passing a Colors slice with exactly one element, e.g. (dict "Colors" (slice "000000ff")). Empty Colors is safe (defaults applied); one color is rejected.

Common situations: Developer wants a monochrome look and lists only black, forgetting the white counterpart; or a conditional slice construction ends up with a single element.

Related errors


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