[NOTABUG] Race condition around scratch variables?

I think I’ve uncovered a race condition in…something. I have a minimal test site available at {removed} on GitHub. When I run hugo (currently v0.54.0 through Homebrew), I don’t always get the same output in public/ between successive runs.

To see what I mean, download and unpack the site to a directory and run make a bunch of times. While sometimes successive runs of hugo will generate identical public/ directory trees, sometimes they won’t. Here’s a copy of what happened on one of the times that they differed:

--- p2/contact/index.html	2019-03-18 21:39:44.000000000 -0700
+++ public/contact/index.html	2019-03-18 21:39:44.000000000 -0700
@@ -31,7 +31,7 @@
 <dd>
 
 <dt>title
-<dd>Home Page
+<dd>
 
 <dt>color
 <dd>#5fb5b4

Here’s another where the color differs:

--- p2/colophon/index.html	2019-03-18 21:40:18.000000000 -0700
+++ public/colophon/index.html	2019-03-18 21:40:18.000000000 -0700
@@ -31,10 +31,10 @@
 <dd>
 
 <dt>title
-<dd>
+<dd>Home Page
 
 <dt>color
-<dd>#781bc0
+<dd>#5fb5b4
 
 </dl>

Sometimes only the color differs (on, say, pages other than the home page):

--- p2/privacy/index.html	2019-03-18 21:42:41.000000000 -0700
+++ public/privacy/index.html	2019-03-18 21:42:41.000000000 -0700
@@ -34,7 +34,7 @@
 <dd>Home Page
 
 <dt>color
-<dd>#5fb5b4
+<dd>#781bc0
 
 </dl>

I wouldn’t even know where to begin to hunt down the cause of this. Should I add an issue on the GitHub tracker?

No. That Hugo does parallel processing is one of the reasons why Hugo runs so fast. It looks like you reuse the same .Scratch in different template context with different values and depend on an order that isn’t there.

You may want to use:

{{ $scratch := newScratch }}

To make sure you get a “scratch for yourself”.

1 Like

That did it. Thanks!

For anyone else who might get tripped up, but can’t see the repo: I was using $.Scratch in a partial and then passing that scratch on to a second partial. This is racy; don’t do it. Making a new scratch variable, setting “href”, “color”, and “title” on that, and then passing that scratch variable on to a second partial fixed it.

1 Like

Hard to say without seeing your code, but there is also the dict func that is common to use for passing more than one variable to a partial.