"You may have a circular loop in a shortcode" problem

Hi, I’m using a custom shortcode (xref) to create cross-references in a documentation. Basically, it looks up the referenced file and returns its title, or if the reference includes an anchor (like /docs/_index.md#myanchor), it tries to find the anchor in the TableOfContents of the referenced page, and returns its title. It is working well except for the following edge case:

If there are two pages that xref to each other and both xrefs have anchors, then I get the following error: “timed out initializing value. You may have a circular loop in a shortcode, or your site may have resources that take longer to build than the timeout limit in your Hugo config file.”

Increasing the timeout doesn’t help.

The shortcode is the following:

{{- $file := .Get 0 -}}
{{- $fullref := (relref . $file) -}}
{{- $pageref := (replaceRE "#.*$" "" $fullref) -}}
{{- $scratch := newScratch -}}

{{- if eq $pageref "" -}}
  {{- errorf "xref cannot handle header refs on caller page; %s" .Position -}}
{{- else -}}
  {{- range .Site.Pages -}}
    {{- if eq $pageref .RelPermalink -}}
      {{- $scratch.Set "page" . -}}
    {{- end -}}
  {{- end -}}
{{- end -}}

{{- if (findRE "#.*$" $file) -}}
  {{- $anchor := (strings.TrimPrefix $pageref $fullref) -}}
  {{- $page := ($scratch.Get "page") -}}
  {{- $toc_line := (findRE (print "<li><a href=\"" $anchor "\">(.*)</a>") $page.TableOfContents) -}}
  {{- if eq (len $toc_line) 0 -}}
    {{- errorf "Failed to extract header title for anchor %q on page %q" $anchor $pageref -}}
  {{- end -}}
  {{- $header := (replaceRE (print "<li><a href=\"" $anchor "\">(.*)</a>") "$1" (index $toc_line 0)) | safeHTML -}}
  [{{- $header }}]({{ print $page.RelPermalink $anchor -}})
{{- else -}}
  {{- $page := ($scratch.Get "page") -}}
  {{ print "[" $page.Title "](" $page.RelPermalink ")" | markdownify }}
{{- end -}}

I’ve created a minimal test repository at GitHub - fekete-robert/xref-shortcode-debug: Example site to debug the xref shortcode ,where the shortcode is in layouts/shortcodes/xref.html, and the files content/about.md and content/_index.md xref each other.

Do you have any idea how to avoid the error? Thanks for your help :slight_smile:

The following page variables force evaluation of a page’s RawContent:

  • Content
  • FuzzyWordCount
  • Plain
  • PlainWords
  • ReadingTime
  • Summary (regardless of whether or not it is defined in front matter)
  • TableOfContents
  • Truncated
  • WordCount

Page A is trying to evaluate the RawContent of Page B, which is trying to evaluate the RawContent of Page A, which is trying to evaluate the RawContent of Page B, etc.

So that’s indeed a circular loop. Many thanks for clarifying that, I’ll see if I can find some other solution.

Silly question, but is there a way to detect the loop and fallback to a different part of the code? Something like the try/except pair in Python?

No. See https://github.com/gohugoio/hugo/issues/9737.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.