Using with does not prevent nil pointer dereference for image exif

The docs on image processing suggest that you should use “with” to wrap access to Exif data in case there are non JPG or TIFF images. This does not seem to prevent Hugo erroring with a “nil pointer dereference” for me. In my custom shortcode I have:

{{- $caption := (.Get "caption") }}
{{- with $image.Exif }}
    {{- $caption := .Tags.ImageDescription }}
{{- end }}

Where the intention is to use the provided caption, unless there is a description in the Exif data.

This works on JPGs, but when I add a PNG I get:

ERROR 2020/09/14 11:18:16 "anarticle.md:13:1": failed to render shortcode "image": failed to process shortcode: "filepath/layouts/shortcodes/image.html:5:15": execute of template failed: template: shortcodes/image.html:5:15: executing "shortcodes/image.html" at <$image.Exif>: error calling Exif: runtime error: invalid memory address or nil pointer dereference

Would appreciate any thoughts on why this doesn’t work.

Based on the documentation and this forum topic, using with should avoid the error. Perhaps the documentation was based on bep’s suggestion, but never tested.

Unless you have any objections, I’ll create a GitHib issue with a minimal failing example.

Side note: in your code you initialize $caption twice, instead of initializing it (:=) and then assigning its value (=). This will not provide the results you expect. For example:

{{- $a := "foo" -}}
{{- $b := "bar" -}}
{{- with $a -}}
  {{- $b := "baz" -}}
{{- end -}}
{{ $b }} <!-- prints "bar" not "baz" -->

Do it like this instead:

{{- $a := "foo" -}}
{{- $b := "bar" -}}
{{- with $a -}}
  {{- $b = "baz" -}}
{{- end -}}
{{ $b }} <!-- prints "baz" -->
1 Like

In this case, both image and Exif can be nil, so you would need a double with:

{{- with $image}}
{{ with .Exif }}
    {{- $caption := .Tags.ImageDescription }}
{{ end }}
{{- end }}

Thanks for producing the example and posting the issue (and for pointing out the other errors in my template).

Is there any workaround to this that does not involve using “with”?

{{- range $image := resources.Match "images/*" -}}
  {{- if ne "png" $image.MediaType.SubType -}}
    {{ $image.Exif.Tags.ImageDescription }}<br>
  {{- end -}}
{{- end -}}
1 Like

Fixed in v0.75.1 with https://github.com/gohugoio/hugo/pull/7693.

1 Like