gohugoio/hugo · error
%T is not an image filter
Error message
%T is not an image filter
What it means
Thrown by images.ToFilters when the input is not a filter, a slice of filters, or a single filter wrapper (image.go:492-506). ToFilters is used internally by image processing pipelines to normalize a heterogeneous argument list into []gift.Filter; unrecognized types panic with the concrete Go type (%T).
Source
Thrown at resources/images/image.go:505
}
return in
}
// ToFilters converts the given input to a slice of gift.Filter.
func ToFilters(in any) []gift.Filter {
switch v := in.(type) {
case []gift.Filter:
return v
case []filter:
vv := make([]gift.Filter, len(v))
for i, f := range v {
vv[i] = f
}
return vv
case gift.Filter:
return []gift.Filter{v}
default:
panic(fmt.Sprintf("%T is not an image filter", in))
}
}
// IsOpaque returns false if the image has alpha channel and there is at least 1
// pixel that is not (fully) opaque.
func IsOpaque(img image.Image) bool {
if oim, ok := img.(interface {
Opaque() bool
}); ok {
return oim.Opaque()
}
return false
}
// ImageSource identifies and decodes an image.
type ImageSource interface {
DecodeImage() (image.Image, error)View on GitHub (pinned to 52c9bd7908)
Solutions
- Ensure every element is produced by an images.* filter constructor (Process, Text, Padding, Dither, etc.).
- Do not append raw scalars, resources, or maps to a filter slice.
- Inspect the printed type (%T) to find the offending element.
Example fix
// before
{{ $filters := slice }}
{{ $filters = $filters | append "#ffffff" }}
{{ $img := $img.Filter $filters }}
// after
{{ $filters := slice }}
{{ $filters = $filters | append (images.Padding 10 "#ffffff") }}
{{ $img := $img.Filter $filters }} Defensive patterns
Strategy: type-guard
Validate before calling
{{ range $f := $filters }}
{{ if not (reflect.IsMap $f) }}{{ end }}
{{ end }} Type guard
// IsGiftFilter reports whether v can be accepted by images.ToFilters.
func IsGiftFilter(v any) bool {
switch v.(type) {
case gift.Filter, []gift.Filter, images.FilterWrapper:
return true
}
return false
} Prevention
- Only append results of images.* filter constructors to filter slices.
- Avoid mixing scalar/resource values into a filter list.
- Inspect the %T in the error to locate the bad element.
When it happens
Trigger: Passing a non-filter value (string, int, map, arbitrary struct) where a filter is expected — typically via the images.Process filter list or when manually building a filter slice with mixed types.
Common situations: Template builds a filter slice and accidentally appends a plain value (e.g. a color string or a resource) instead of a filter produced by images.* functions.
Related errors
- aligny must be one of top, center, bottom
- invalid text font source: %T
- the padding filter requires between 1 and 5 arguments
- invalid canvas color: specify RGB or RGBA using hex notation
- not enough arguments: provide one or more padding values usi
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/b9d4bc3d379a984c.
Report an issue: GitHub.