Repository: gohugoio/hugo (language: go)

Issue:
Unexpected template resolution (intermittent) when layout specified in front matter
In the test below, the layout specified in front matter does not exist, so I would expect it to fallback to `layouts/single.html`. It intermittently falls back to `layouts/list.html` instead.


```go
func TestIssue13628(t *testing.T) {
	t.Parallel()

	files := `
-- hugo.toml --
disableKinds = ['home','rss','sitemap','taxonomy','term']
-- content/p1.md --
---
title: p1
layout: foo
---
-- layouts/single.html --
layouts/single.html
-- layouts/list.html --
layouts/list.html
`

	b := hugolib.Test(t, files)

	b.AssertFileContent("public/p1/index.html", "layouts/single.html") 
}
```

EDIT: There's something intermittent happening here.




Discussion / hints:
This fails after 1-10 iterations:

```go
func TestIssue13628(t *testing.T) {
	t.Parallel()

	files := `
-- hugo.toml --
disableKinds = ['home','rss','sitemap','taxonomy','term']
-- content/p1.md --
---
title: p1
layout: foo
---
-- layouts/single.html --
layouts/single.html
-- layouts/list.html --
layouts/list.html
`

	var b *hugolib.IntegrationTestBuilder

	for i := 1; i < 100; i++ {
		b = hugolib.Test(t, files)
		if b.FileContent("public/p1/index.html") != "layouts/single.html" {
			fmt.Printf("failed after %d iterations\n", i)
			t.FailNow()
		}
	}
}
```
This was also the cause for this: https://discourse.gohugo.io/t/possible-race-condition-with-readfile-in-0-146-3/54366/5

Fix patch:
diff --git a/tpl/tplimpl/templatedescriptor.go b/tpl/tplimpl/templatedescriptor.go
index 8e4390faebd..ca73c9f7832 100644
--- a/tpl/tplimpl/templatedescriptor.go
+++ b/tpl/tplimpl/templatedescriptor.go
@@ -177,7 +177,7 @@ func (this TemplateDescriptor) doCompare(category Category, isEmbedded bool, oth
 		w.w2 = weight2Group1
 	}
 
-	if this.LayoutFromUser == "" && other.LayoutFromTemplate != "" && (other.LayoutFromTemplate == this.LayoutFromTemplate || other.LayoutFromTemplate == layoutAll) {
+	if other.LayoutFromTemplate != "" && (other.LayoutFromTemplate == this.LayoutFromTemplate || other.LayoutFromTemplate == layoutAll) {
 		w.w1 += weightLayoutStandard
 		w.w2 = weight2Group1
 


Test patch:
diff --git a/tpl/tplimpl/templatestore_integration_test.go b/tpl/tplimpl/templatestore_integration_test.go
index 32e1248fe27..e59dad33a52 100644
--- a/tpl/tplimpl/templatestore_integration_test.go
+++ b/tpl/tplimpl/templatestore_integration_test.go
@@ -1204,3 +1204,28 @@ layouts/_partials/comment.ru.xml
 	b.AssertFileContent("public/ru/index.html", "layouts/_partials/comment.ru.html") // fail
 	b.AssertFileContent("public/ru/index.xml", "layouts/_partials/comment.ru.xml")   // fail
 }
+
+func TestLayoutIssue13628(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- hugo.toml --
+disableKinds = ['home','rss','sitemap','taxonomy','term']
+-- content/p1.md --
+---
+title: p1
+layout: foo
+---
+-- layouts/single.html --
+layouts/single.html
+-- layouts/list.html --
+layouts/list.html
+`
+
+	for range 5 {
+
+		b := hugolib.Test(t, files)
+
+		b.AssertFileContent("public/p1/index.html", "layouts/single.html")
+	}
+}