Repository: gohugoio/hugo (language: go)

Issue:
Multiple `templates.Defer` in same tamplate panic: deferred execution with id not found
<!--
Please do not use the issue queue for questions or troubleshooting. Unless you are certain that your issue is a software defect, use the forum:

https://discourse.gohugo.io
-->

<!-- Please answer these questions before submitting your issue. Thanks! -->

### What version of Hugo are you using (`hugo version`)?

<pre>
$ hugo version
hugo v0.140.2-aae02ca612a02e085c08366a9c9279f4abb39d94+extended linux/amd64 BuildDate=2024-12-30T15:01:53Z VendorInfo=snap:0.140.2
</pre>

### Does this issue reproduce with the latest release?

Yes

### Code Snippets

```html
{{ with (templates.Defer (dict "data" (dict "foo" "bar") )) }}
{{ end }}
{{ with (templates.Defer (dict "data" (dict "fizz" "buzz") )) }}
{{ end }}
```

It works after removing others `Defer`.

### Panic Log

```log
panic: deferred execution with id "__hdeferred/cafc7706cee4572b_12__d=" not found

goroutine 247 [running]:
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func1.1(0xc001413901?, {0xc0015cc630, 0x23}, 0xc000257680, 0xc001273e88, 0xc001273ea0, 0xa01, 0xa24, 0xc001273e47)
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:469 +0x468
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func1({0xc000a36f8d, 0x27})
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:502 +0x247
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func2({0xc001273f38?, 0xc001273f18?}, {0xc000a36f8d?, 0x0?})
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:519 +0x22
github.com/gohugoio/hugo/common/rungroup.Run[...].func1()
        /build/hugo/parts/hugo/build/common/rungroup/rungroup.go:64 +0xbd
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /build/hugo/parts/hugo/go/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:78 +0x56
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 123
        /build/hugo/parts/hugo/go/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:75 +0x96
panic: deferred execution with id "__hdeferred/cafc7706cee4572b_2__d=" not found

goroutine 251 [running]:
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func1.1(0xc001832978?, {0xc00177d1d0, 0x22}, 0xc000257680, 0xc00126be88, 0xc00126bea0, 0x978, 0x99a, 0xc00126be47)
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:469 +0x468
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func1({0xc000dc1e6d, 0xb})
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:502 +0x247
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func2({0xc00126bf38?, 0xc00126bf18?}, {0xc000dc1e6d?, 0x0?})
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:519 +0x22
github.com/gohugoio/hugo/common/rungroup.Run[...].func1()
        /build/hugo/parts/hugo/build/common/rungroup/rungroup.go:64 +0xbd
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /build/hugo/parts/hugo/go/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:78 +0x56
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 123
        /build/hugo/parts/hugo/go/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:75 +0x96
panic: deferred execution with id "__hdeferred/cafc7706cee4572b_4__d=" not found

goroutine 255 [running]:
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func1.1(0xc001a00997?, {0xc001b00000, 0x22}, 0xc000257680, 0xc001263e88, 0xc001263ea0, 0x997, 0x9b9, 0xc001263e47)
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:469 +0x468
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func1({0xc0007b8e3d, 0x16})
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:502 +0x247
github.com/gohugoio/hugo/hugolib.(*Site).executeDeferredTemplates.func2({0xc001263f38?, 0xc001263f18?}, {0xc0007b8e3d?, 0x0?})
        /build/hugo/parts/hugo/build/hugolib/hugo_sites_build.go:519 +0x22
github.com/gohugoio/hugo/common/rungroup.Run[...].func1()
        /build/hugo/parts/hugo/build/common/rungroup/rungroup.go:64 +0xbd
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /build/hugo/parts/hugo/go/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:78 +0x56
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 123
        /build/hugo/parts/hugo/go/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:75 +0x96
```


Discussion / hints:

Fix patch:
diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go
index 60fb8ecc02f..1518e2db848 100644
--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -508,6 +508,7 @@ func (s *Site) executeDeferredTemplates(de *deps.DeferredExecutions) error {
 				}
 
 				content = append(content[:low], append([]byte(deferred.Result), content[high:]...)...)
+				forward = len(deferred.Result)
 				changed = true
 
 				return nil


Test patch:
diff --git a/tpl/templates/defer_integration_test.go b/tpl/templates/defer_integration_test.go
index 8b06e772242..77be91cee84 100644
--- a/tpl/templates/defer_integration_test.go
+++ b/tpl/templates/defer_integration_test.go
@@ -220,3 +220,30 @@ Home
 	b.Assert(err, qt.Not(qt.IsNil))
 	b.Assert(err.Error(), qt.Contains, "resources.PostProcess cannot be used in a deferred template")
 }
+
+// Issue #13236.
+func TestDeferMultipleInSameTemplate(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- hugo.toml --
+-- layouts/index.html --
+Home.
+...
+{{ with (templates.Defer (dict "data" (dict "a" "b") )) }}
+ Defer 1
+{{ end }}
+...
+{{ with (templates.Defer (dict "data" (dict "a" "c") )) }}
+Defer 2
+{{ end }}
+{{ with (templates.Defer (dict "data" (dict "a" "d") )) }}
+Defer 3
+{{ end }}{{ with (templates.Defer (dict "data" (dict "a" "d") )) }}{{ end }}
+End.
+`
+
+	b := hugolib.Test(t, files)
+
+	b.AssertFileContent("public/index.html", "Home.", "Defer 1", "Defer 2", "Defer 3", "End.")
+}