Repository: gruntwork-io/terragrunt (language: go)

Issue:
Terragrunt Error removing manifest file
**Terragrunt Error removing manifest file**
I'm constantly getting the error removing .\terragrunt-module-manifest manifest file cannot run anything Terragrunt init, plan, apply, destroy nothing works.

![Screenshot 2023-12-21 121936](https://github.com/gruntwork-io/terragrunt/assets/103419632/a2397ecd-8a15-4b9f-a63b-23a82500deae)

Note : it was working fine till yesterday, my credentials are correct and terraform works fine.

**Expected behavior**
No error is expected.

**Versions**
- Terragrunt version: v0.53.8
- Terraform version: v1.6.5



Discussion / hints:
Hi,
the issue still happen after the removal of .terragrunt-cache directory? and re-run of jobs?
Problem for me too. Clear of files, still get the same error
> Hi, the issue still happen after the removal of .terragrunt-cache directory? and re-run of jobs?

The first run (after deletion) is ok, bit any consecutive run then shows the error again...

Fix patch:
diff --git a/util/file.go b/util/file.go
index abcc5c27ff..2988bd2551 100644
--- a/util/file.go
+++ b/util/file.go
@@ -495,7 +495,15 @@ func (manifest *fileManifest) clean(manifestPath string) error {
 	if err != nil {
 		return err
 	}
-	defer file.Close()
+	// cleaning manifest file
+	defer func(name string) {
+		if err := file.Close(); err != nil {
+			GlobalFallbackLogEntry.Warnf("Error closing file %s: %v", name, err)
+		}
+		if err := os.Remove(name); err != nil {
+			GlobalFallbackLogEntry.Warnf("Error removing manifest file %s: %v", name, err)
+		}
+	}(manifestPath)
 	decoder := gob.NewDecoder(file)
 	// decode paths one by one
 	for {
@@ -519,15 +527,6 @@ func (manifest *fileManifest) clean(manifestPath string) error {
 			}
 		}
 	}
-	// remove the manifest itself
-	// it will run after the close defer
-	defer func(name string) {
-		err := os.Remove(name)
-		if err != nil {
-			GlobalFallbackLogEntry.Warnf("Error removing manifest file %s: %v", name, err)
-		}
-	}(manifestPath)
-
 	return nil
 }
 


Test patch:
diff --git a/test/fixture-manifest-removal/app/main.tf b/test/fixture-manifest-removal/app/main.tf
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixture-manifest-removal/app/terragrunt.hcl b/test/fixture-manifest-removal/app/terragrunt.hcl
new file mode 100644
index 0000000000..70a260c31c
--- /dev/null
+++ b/test/fixture-manifest-removal/app/terragrunt.hcl
@@ -0,0 +1,6 @@
+terraform {
+  source = "."
+}
+include "root" {
+  path = find_in_parent_folders()
+}
\ No newline at end of file
diff --git a/test/fixture-manifest-removal/terragrunt.hcl b/test/fixture-manifest-removal/terragrunt.hcl
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/integration_windows_test.go b/test/integration_windows_test.go
index a181a84a66..8809ab1147 100644
--- a/test/integration_windows_test.go
+++ b/test/integration_windows_test.go
@@ -19,6 +19,7 @@ import (
 
 const (
 	TEST_FIXTURE_LOCAL_RELATIVE_ARGS_WINDOWS_DOWNLOAD_PATH = "fixture-download/local-relative-extra-args-windows"
+	TEST_FIXTURE_MANIFEST_REMOVAL                          = "fixture-manifest-removal"
 )
 
 func TestWindowsLocalWithRelativeExtraArgsWindows(t *testing.T) {
@@ -87,6 +88,49 @@ func TestWindowsTflintIsInvoked(t *testing.T) {
 	assert.True(t, found)
 }
 
+func TestWindowsManifestFileIsRemoved(t *testing.T) {
+	out := new(bytes.Buffer)
+	errOut := new(bytes.Buffer)
+	rootPath := copyEnvironmentWithTflint(t, TEST_FIXTURE_MANIFEST_REMOVAL)
+	modulePath := util.JoinPath(rootPath, TEST_FIXTURE_MANIFEST_REMOVAL, "app")
+	err := runTerragruntCommand(t, fmt.Sprintf("terragrunt plan --terragrunt-non-interactive --terragrunt-log-level debug --terragrunt-working-dir %s", modulePath), out, errOut)
+	assert.NoError(t, err)
+
+	info1, err := fileInfo(modulePath, ".terragrunt-module-manifest")
+	assert.NoError(t, err)
+	assert.NotNil(t, info1)
+
+	out = new(bytes.Buffer)
+	errOut = new(bytes.Buffer)
+	err = runTerragruntCommand(t, fmt.Sprintf("terragrunt plan --terragrunt-non-interactive --terragrunt-log-level debug --terragrunt-working-dir %s", modulePath), out, errOut)
+	assert.NoError(t, err)
+
+	info2, err := fileInfo(modulePath, ".terragrunt-module-manifest")
+	assert.NoError(t, err)
+	assert.NotNil(t, info2)
+
+	// ensure that .terragrunt-module-manifest was recreated
+	assert.True(t, (*info2).ModTime().After((*info1).ModTime()))
+}
+
+func fileInfo(path, fileName string) (*os.FileInfo, error) {
+	var fileInfo *os.FileInfo
+	err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
+		if fileInfo != nil {
+			return nil
+		}
+		if err != nil {
+			return err
+		}
+		if !info.IsDir() && info.Name() == fileName {
+			fileInfo = &info
+			return nil
+		}
+		return nil
+	})
+	return fileInfo, err
+}
+
 func copyEnvironmentToPath(t *testing.T, environmentPath, targetPath string) {
 	if err := os.MkdirAll(targetPath, 0777); err != nil {
 		t.Fatalf("Failed to create temp dir %s due to error %v", targetPath, err)