Repository: gohugoio/hugo (language: go)

Issue:
Nilpointer in dartsass.Close
Note that this error most likely masks an underlying error: In Hugo 0.139.0 we removed support for v1 of the Dart Sass embedded protocol (binaries named `dart-sass-embedded`). These are very old versions, but I guess still in use.

See https://discourse.gohugo.io/t/panic-when-building-on-netlify/52486

```
8:05:27 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
8:05:26 PM: Total in 114717 ms
8:05:26 PM: panic: runtime error: invalid memory address or nil pointer dereference
8:05:26 PM: [signal SIGSEGV: segmentation violation code=0x1 addr=0x8c pc=0x9cbdb9]
8:05:26 PM: goroutine 1 [running]:
8:05:26 PM: github.com/bep/godartsass/v2.(*Transpiler).Close(0x0)
8:05:26 PM: 	/root/project/gomodcache/github.com/bep/godartsass/v2@v2.3.0/transpiler.go:173 +0x39
8:05:26 PM: github.com/gohugoio/hugo/resources/resource_transformers/tocss/dartsass.(*Client).Close(0xc00082f8ac?)
8:05:26 PM: 	/root/project/hugo/resources/resource_transformers/tocss/dartsass/client.go:108 +0x17
8:05:26 PM: github.com/gohugoio/hugo/common/types.(*Closers).Close(0xc0003f7b20)
8:05:26 PM: 	/root/project/hugo/common/types/closer.go:41 +0x8c
8:05:26 PM: github.com/gohugoio/hugo/deps.(*Deps).Close(0xc0007a2690)
8:05:26 PM: 	/root/project/hugo/deps/deps.go:361 +0x5e
8:05:26 PM: github.com/gohugoio/hugo/commands.(*rootCommand).Close.func1({0x1ce4b60?, 0x0?}, 0xc00025d230?)
8:05:26 PM: 	/root/project/hugo/commands/commandeer.go:160 +0x1f
8:05:26 PM: github.com/bep/lazycache.(*Cache[...]).DeleteFunc(0x2405d40, 0x2216008)
8:05:26 PM: 	/root/project/gomodcache/github.com/bep/lazycache@v0.7.0/lazycache.go:68 +0x197
8:05:26 PM: github.com/gohugoio/hugo/commands.(*rootCommand).Close(0x3127230?)
8:05:26 PM: 	/root/project/hugo/commands/commandeer.go:158 +0x2a
8:05:26 PM: github.com/gohugoio/hugo/commands.Execute({0xc000138090, 0x3, 0x3})
8:05:26 PM: 	/root/project/hugo/commands/commandeer.go:71 +0x41d
8:05:26 PM: main.main()
8:05:26 PM: 	/root/project/hugo/main.go:25 +0x56
```


Discussion / hints:

Fix patch:
diff --git a/resources/resource_transformers/tocss/dartsass/client.go b/resources/resource_transformers/tocss/dartsass/client.go
index 470c18b97df..4ab958c01c2 100644
--- a/resources/resource_transformers/tocss/dartsass/client.go
+++ b/resources/resource_transformers/tocss/dartsass/client.go
@@ -44,7 +44,7 @@ const dartSassStdinPrefix = "hugostdin:"
 
 func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) (*Client, error) {
 	if !Supports() {
-		return &Client{dartSassNotAvailable: true}, nil
+		return &Client{}, nil
 	}
 
 	if hugo.DartSassBinaryName == "" {
@@ -89,22 +89,25 @@ func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) (*Client, error)
 }
 
 type Client struct {
-	dartSassNotAvailable bool
-	rs                   *resources.Spec
-	sfs                  *filesystems.SourceFilesystem
-	workFs               afero.Fs
+	rs     *resources.Spec
+	sfs    *filesystems.SourceFilesystem
+	workFs afero.Fs
 
+	// This may be nil if Dart Sass is not available.
 	transpiler *godartsass.Transpiler
 }
 
 func (c *Client) ToCSS(res resources.ResourceTransformer, args map[string]any) (resource.Resource, error) {
-	if c.dartSassNotAvailable {
+	if c.transpiler == nil {
 		return res.Transform(resources.NewFeatureNotAvailableTransformer(transformationName, args))
 	}
 	return res.Transform(&transform{c: c, optsm: args})
 }
 
 func (c *Client) Close() error {
+	if c.transpiler == nil {
+		return nil
+	}
 	return c.transpiler.Close()
 }
 


Test patch:
diff --git a/resources/resource_transformers/cssjs/postcss_integration_test.go b/resources/resource_transformers/cssjs/postcss_integration_test.go
index e8f52326cf3..8f2132789ad 100644
--- a/resources/resource_transformers/cssjs/postcss_integration_test.go
+++ b/resources/resource_transformers/cssjs/postcss_integration_test.go
@@ -70,7 +70,7 @@ hello:
    other: "Bonjour"
 -- layouts/index.html --
 {{ $options := dict "inlineImports" true }}
-{{ $styles := resources.Get "css/styles.css" | resources.PostCSS $options }}
+{{ $styles := resources.Get "css/styles.css" | css.PostCSS $options }}
 Styles RelPermalink: {{ $styles.RelPermalink }}
 {{ $cssContent := $styles.Content }}
 Styles Content: Len: {{ len $styles.Content }}|