diff --git a/CHANGES.md b/CHANGES.md
index 1a32103bf0..c714552607 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -10,6 +10,8 @@ This document is intended for Spotless developers.
 We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
 
 ## [Unreleased]
+### Fixed
+* Node.JS-based tasks now work with the configuration cache ([#2372](https://github.com/diffplug/spotless/issues/2372))
 
 ## [3.0.1] - 2025-01-07
 ### Fixed
diff --git a/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java b/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java
index 317c2a479b..f62340f074 100644
--- a/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java
+++ b/lib/src/main/java/com/diffplug/spotless/npm/NpmPathResolver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2024 DiffPlug
+ * Copyright 2020-2025 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
 
 import java.io.File;
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 
@@ -35,7 +36,9 @@ public NpmPathResolver(File explicitNpmExecutable, File explicitNodeExecutable,
 		this.explicitNpmExecutable = explicitNpmExecutable;
 		this.explicitNodeExecutable = explicitNodeExecutable;
 		this.explicitNpmrcFile = explicitNpmrcFile;
-		this.additionalNpmrcLocations = List.copyOf(additionalNpmrcLocations);
+		// We must not use an immutable list (e.g. List.copyOf) here, because immutable lists cannot be restored
+		// from Gradle’s serialisation. See https://github.com/diffplug/spotless/issues/2372
+		this.additionalNpmrcLocations = new ArrayList<>(additionalNpmrcLocations);
 	}
 
 	/**
diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md
index 6b9b44181f..077f18125d 100644
--- a/plugin-gradle/CHANGES.md
+++ b/plugin-gradle/CHANGES.md
@@ -3,6 +3,8 @@
 We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).
 
 ## [Unreleased]
+### Fixed
+ * Node.JS-based tasks now work with the configuration cache ([#2372](https://github.com/diffplug/spotless/issues/2372))
 
 ## [7.0.1] - 2025-01-07
 ### Fixed
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest.java
index 22fe466dbe..6abbc108fa 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2024 DiffPlug
+ * Copyright 2016-2025 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -177,4 +177,15 @@ void useNpmNextToConfiguredNodePluginFromNodeGradlePlugin() throws Exception {
 			throw e;
 		}
 	}
+
+	@Test
+	public void supportsConfigurationCache() throws Exception {
+		setFile("build.gradle").toResource("com/diffplug/gradle/spotless/NpmTestsWithoutNpmInstallationTest_gradle_node_plugin_example_1.gradle");
+		setFile("test.ts").toResource("npm/prettier/config/typescript.dirty");
+		BuildResult spotlessApply = gradleRunner()
+				.withGradleVersion(GradleVersionSupport.STABLE_CONFIGURATION_CACHE.version)
+				.withArguments("--stacktrace", "--configuration-cache", "spotlessApply").build();
+		Assertions.assertThat(spotlessApply.getOutput()).contains("BUILD SUCCESSFUL");
+		assertFile("test.ts").sameAsResource("npm/prettier/config/typescript.configfile_prettier_2.clean");
+	}
 }