HUGO

Multilingual-related .Page.RenderString regression in 0.92

Where 0.91.2 worked just fine, 0.92.0 fails to build a site for me:

Error: Error building site: “[mysite]/content/[somewhere]/index.en.md:21:1”: failed to render shortcode “image”: failed to process shortcode: “[mysite]/themes/[sometheme]/layouts/shortcodes/image.html:2:64”: execute of template failed: template: shortcodes/image.html:2:64: executing “shortcodes/image.html” at <.Page.RenderString>: error calling RenderString: runtime error: invalid memory address or nil pointer dereference

The line in the shortcode is:

{{- $options = cond .IsNamedParams (.Get "alt") (.Get 1) | .Page.RenderString | dict "Alt" | merge $options -}}

and it is called from the index.md in question like this:

{{< image src="pre.png" alt="before" caption="May 2020" >}}

Looks like nothing criminal is going on here, at least nothing that would warrant a nil pointer dereference. Also, 0.92.0 release notes say nothing about changes in .Page.RenderString, so I’m guessing this is a side-effect of the whole .Page rework — and a regression. Right?

Can we see the complete shortcode?

This works fine with v0.92.0…

layouts/shortcodes/image.html

{{ $options := dict }}
{{ $options = cond .IsNamedParams (.Get "alt") (.Get 1) | .Page.RenderString | dict "Alt" | merge $options }}
{{ $options.Alt }}

content/post/test.md

{{< image src="pre.png" alt="before" caption="May 2020" >}}

Here’s the offender in full:

{{- $options := cond .IsNamedParams (.Get "src") (.Get 0) | dict "Src" -}}
{{- $options = cond .IsNamedParams (.Get "alt") (.Get 1) | .Page.RenderString | dict "Alt" | merge $options -}}
{{- $caption := cond .IsNamedParams (.Get "caption") (.Get 2) | .Page.RenderString -}}
{{- $options = dict "Caption" $caption | merge $options -}}

{{- if .IsNamedParams -}}
    {{- $options = dict "Title" (.Get "title") | merge $options -}}
    {{- $options = dict "SrcSmall" (.Get "src_s") | merge $options -}}
    {{- $options = dict "SrcLarge" (.Get "src_l") | merge $options -}}
    {{- $options = dict "Height" (.Get "height") | merge $options -}}
    {{- $options = dict "Width" (.Get "width") | merge $options -}}
    {{- $options = .Get "linked" | ne false | dict "Linked" | merge $options -}}
    {{- $options = dict "Rel" (.Get "rel") | merge $options -}}
{{- else -}}
    {{- $options = cond $caption true false | dict "Linked" | merge $options -}}
{{- end -}}

{{- $options = dict "Resources" .Page.Resources | merge $options -}}

{{- $img := .Page.Resources.GetMatch $options.Src -}}
{{- with $img -}}{{- $featured := in $img.Name "feature" -}}
{{- if $featured -}}{{- $options = dict "Class" "u-photo" | merge $options -}}{{- end -}}
{{- end -}}

{{- with $caption -}}
    <figure{{ with cond $.IsNamedParams ($.Get "class") "" }} class="{{ . }}"{{ end }}>
        {{- partial "plugin/image.html" $options -}}
        <figcaption class="image-caption">
            {{- . | safeHTML -}}
        </figcaption>
    </figure>
{{- else -}}
    {{- partial "plugin/image.html" $options -}}
{{- end -}}

I commented out the two partial calls to plugin/image.html because you have not shared that template. No errors.

I’d recommend sharing your entire project if you need additional assistance.

I can’t share the whole project (for several reasons), but I can share a part that reproduces the issue. This archive contains config, a couple of pages and a snapshot of the theme; trying to build it with 0.92.0 results in the cryptic error, while 0.91.2 builds ok.

This is what I did:

wget https://evgenykuznetsov.org/feeds/mvp.tar.gz
tar -xvzf mvp.tar.gz
cd mvp/
hugo

This is what I got:

Start building sites … 
hugo v0.92.0-B3549403+extended linux/amd64 BuildDate=2022-01-12T08:23:18Z VendorInfo=gohugoio

                   | RU | EN  
-------------------+----+-----
  Pages            | 12 | 11  
  Paginator pages  |  0 |  0  
  Non-page files   |  0 |  0  
  Static files     | 83 | 83  
  Processed images |  1 |  0  
  Aliases          |  1 |  0  
  Sitemaps         |  2 |  1  
  Cleaned          |  0 |  0  

Total in 169 ms

No errors.

I just noticed that your tarball doesn’t have any content.

Yes, sorry about that; fixed and reuploaded, reproducible now.

I can’t understand at which point I lost /content the first time…

It also complains about lacking the git log (understandably), but that error isn’t the one that’s fatal.

OK, I can now reproduce with v0.92.0, but not with v0.91.2.

I’ll try to take a look at this a little later.

1 Like

I would highly appreciate you looking at it!

So far, it seems to me to be multilingual-related, very resembling of issue 7292 that was remarkably fixed exactly in this release.

It is. Head scratcher…

Initial findings…

There are two ways to make the problem go away…

  1. In site configuration, disable JSON output. Change this:

    [outputs]
    home = ["HTML", "RSS", "hfeed", "lang", "langRSS", "JSON"]
    

    To this:

    [outputs]
    home = ["HTML", "RSS", "hfeed", "lang", "langRSS"]
    
  2. In site configuration, rename the params.search key. Change this:

    [params.search]
    

    To this:

    [params.xxx-search]
    

Neither of these are solutions, just trying to zero-in on the problem.

No errors with fbb3c18.

Fails with next commit 25d645f.

If I replace your version of the loveit theme with the current version f787a4e there are no errors.

In layouts/index.json, the current version of the loveit theme ranges through .Site.RegularPages.

Your version of the loveit theme does something different. If I revert that one line, the site builds without errors.

If the diff below, a/layouts/index.json is from the current version of the loveit theme, while b/layouts/index.json is from your version of the loveit theme.

diff --git a/layouts/index.json b/layouts/index.json
index 4e81039..9b99f09 100644
--- a/layouts/index.json
+++ b/layouts/index.json
@@ -1,6 +1,6 @@
 {{- if .Site.Params.search -}}
     {{- $index := slice -}}
-    {{- $pages := .Site.RegularPages -}}
+    {{- $pages := partialCached "pageset/reg-pages-all.html" .Site -}}
     {{- if .Site.Params.page.hiddenFromSearch -}}
         {{- $pages = where $pages "Params.hiddenfromsearch" false -}}
     {{- else -}}

MRE

git clone --recurse-submodules --single-branch -b hugo-forum-topic-36555 https://github.com/jmooring/hugo-testing hugo-forum-topic-36555
cd hugo-forum-topic-36555
hugo

It will fail.

Then change the site configuration from:

#theme = "loveit-original"
theme = "loveit-nekr0z"

to:

theme = "loveit-original"
#theme = "loveit-nekr0z"

It will build without errors.

@jmooring Wow! Awesome investigation.

This is very interesting, because it works on the one-page-of-content little piece here, but the whole site (same theme, thousands of content pages) fails — with the same error as before.

Still, whatever breaks .Page.RenderString here seems to be introduced by the pageset/reg-pages-all.html partial, and particularly by the piece of logic that can be stripped down to this:

{{- $pages := .Site.RegularPages -}}
{{- range .Site.Home.Translations -}}
  {{- $pages = $pages | union .Site.RegularPages -}}
{{- end -}}
{{- return $pages -}}

This piece of logic is called as a drop-in replacement for .Site.RegularPages in several places in my modification of the theme.

I think I’ll try to strip the mvp of even more things that don’t affect this issue when I have time. Hopefully it will help to isolate the underlying bug one way or the other.