{"id":"b83302fd479b54e2","repo":"gohugoio/hugo","slug":"must-provide-an-image-and-one-or-more-filters","errorCode":null,"errorMessage":"must provide an image and one or more filters","messagePattern":"must provide an image and one or more filters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/images/images.go","lineNumber":100,"sourceCode":"\treturn ns.cache.GetOrCreate(filename, func() (image.Config, error) {\n\t\tf, err := ns.readFileFs.Open(filename)\n\t\tif err != nil {\n\t\t\treturn image.Config{}, err\n\t\t}\n\t\tdefer f.Close()\n\n\t\text := filepath.Ext(filename)\n\t\tformat, _ := images.ImageFormatFromExt(ext)\n\n\t\tconfig, _, err := ns.deps.ResourceSpec.Imaging.Codec.DecodeConfig(format, f)\n\t\treturn config, err\n\t})\n}\n\n// Filter applies the given filters to the image given as the last element in args.\nfunc (ns *Namespace) Filter(args ...any) (images.ImageResource, error) {\n\tif len(args) < 2 {\n\t\treturn nil, errors.New(\"must provide an image and one or more filters\")\n\t}\n\n\timg := args[len(args)-1].(images.ImageResource)\n\tfiltersv := args[:len(args)-1]\n\n\treturn img.Filter(filtersv...)\n}\n\nvar qrErrorCorrectionLevels = map[string]qr.Level{\n\t\"low\":      qr.L,\n\t\"medium\":   qr.M,\n\t\"quartile\": qr.Q,\n\t\"high\":     qr.H,\n}\n\n// QR encodes the given text into a QR code using the specified options,\n// returning an image resource.\nfunc (ns *Namespace) QR(args ...any) (images.ImageResource, error) {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/images/images.go#L82-L118","documentation":"`images.Filter` applies one or more image filters to an image resource, which by its calling convention (pipe-friendly) is the last argument. With fewer than two arguments there is either no filter or no image, so Hugo rejects the call before attempting the type assertion on the last argument.","triggerScenarios":"Calling `{{ images.Filter $img }}` with no filters, `{{ images.Filter $filter }}` without piping an image, or `{{ $img | images.Filter }}` where the filter list is empty/nil so only one argument reaches the function.","commonSituations":"Building the filter list dynamically (e.g. from `slice`) and it ends up empty; forgetting that the image must be piped in or passed last; copying `.Filter` method examples into the `images.Filter` function form incorrectly.","solutions":["Pass at least one filter plus the image: `{{ $img = $img.Filter (images.GaussianBlur 6) }}` or `{{ images.Filter (images.Grayscale) $img }}`.","If filters are built dynamically, skip the call when the list is empty: `{{ with $filters }}{{ $img = images.Filter . $img }}{{ end }}` (spread as needed).","Check the pipe order — the image must be the last argument (`{{ $img | images.Filter $f1 $f2 }}`)."],"exampleFix":"<!-- before -->\n{{ $img = images.Filter $img }}\n<!-- after -->\n{{ $img = images.Filter (images.Grayscale) $img }}","handlingStrategy":"validation","validationCode":"{{ $img := resources.Get \"photo.jpg\" }}\n{{ $filters := slice (images.GaussianBlur 6) }}\n{{ if and $img (gt (len $filters) 0) }}\n  {{ $img = $img.Filter $filters }}\n{{ end }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call images.Filter with an image resource plus at least one filter","Check resources.Get result with `with` — it returns nil for missing files","Build filter slices with `slice` and confirm they're non-empty before applying"],"tags":["hugo","templates","images","filter","arguments"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}