Repository: kestra-io/kestra
Issue: io.kestra.plugin.git.Push
Labels: bug

### Explain the bug

When running git.Push task with property namespaceFiles enabled and no namespace files exist in the namespace an error is triggered.
In the given example, the branch did not exist. Another run with namespaceFiles: commented out, resulted in a successful run.

Configuration snippet:
```
- id: backup
  type: io.kestra.plugin.git.Push
  namespaceFiles:
    enabled: true
  flows:
    enabled: true
    childNamespaces: true
    gitDirectory: _flows
```

 Stack trace:
```
Branch $BRANCH_NAME does not exist, creating it
Start cloning from 'https://gitlab/'
/$NAMESPACE/_files/ (File not found)
java.io.FileNotFoundException: /$NAMESPACE/_files/ (File not found)
	at io.kestra.storage.minio.MinioStorage.reThrowMinioStorageException(MinioStorage.java:395)
	at io.kestra.storage.minio.MinioStorage.getFileAttributes(MinioStorage.java:154)
	at io.kestra.storage.minio.MinioStorage.getAttributes(MinioStorage.java:138)
	at io.kestra.storage.minio.$MinioStorage$Definition$Intercepted.$$access$$getAttributes(Unknown Source)
	at io.kestra.storage.minio.$MinioStorage$Definition$Exec.dispatch(Unknown Source)
	at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invoke(AbstractExecutableMethodsDefinition.java:371)
	at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:128)
	at io.micronaut.aop.internal.intercepted.SynchronousInterceptedMethod.interceptResult(SynchronousInterceptedMethod.java:55)
	at io.micronaut.retry.intercept.OverrideRetryInterceptor.retrySync(OverrideRetryInterceptor.java:93)
	at io.micronaut.retry.intercept.OverrideRetryInterceptor.intercept(OverrideRetryInterceptor.java:68)
	at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137)
	at io.kestra.storage.minio.$MinioStorage$Definition$Intercepted.getAttributes(Unknown Source)
	at io.kestra.storage.minio.MinioStorage.list(MinioStorage.java:74)
	at io.kestra.storage.minio.$MinioStorage$Definition$Intercepted.$$access$$list(Unknown Source)
	at io.kestra.storage.minio.$MinioStorage$Definition$Exec.dispatch(Unknown Source)
	at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invoke(AbstractExecutableMethodsDefinition.java:371)
	at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:128)
	at io.micronaut.aop.internal.intercepted.SynchronousInterceptedMethod.interceptResult(SynchronousInterceptedMethod.java:55)
	at io.micronaut.retry.intercept.OverrideRetryInterceptor.retrySync(OverrideRetryInterceptor.java:93)
	at io.micronaut.retry.intercept.OverrideRetryInterceptor.intercept(OverrideRetryInterceptor.java:68)
	at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137)
	at io.kestra.storage.minio.$MinioStorage$Definition$Intercepted.list(Unknown Source)
	at io.kestra.core.runners.NamespaceFilesService.recursiveList(NamespaceFilesService.java:80)
	at io.kestra.core.runners.NamespaceFilesService.inject(NamespaceFilesService.java:36)
	at io.kestra.plugin.git.Push.run(Push.java:237)
	at io.kestra.plugin.git.Push.run(Push.java:38)
	at io.kestra.core.runners.Worker$WorkerThread.run(Worker.java:729)
```


### Environment Information

- Kestra Version: 0.14.4
- Operating System and Java Version (if not using Kestra Docker image):
Docker image

Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/core/src/main/java/io/kestra/core/runners/NamespaceFilesService.java b/core/src/main/java/io/kestra/core/runners/NamespaceFilesService.java
index 7986bf0753..59ed961033 100644
--- a/core/src/main/java/io/kestra/core/runners/NamespaceFilesService.java
+++ b/core/src/main/java/io/kestra/core/runners/NamespaceFilesService.java
@@ -9,6 +9,7 @@
 import jakarta.inject.Singleton;
 import lombok.extern.slf4j.Slf4j;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -78,7 +79,13 @@ private List<URI> recursiveList(String tenantId, String namespace, @Nullable URI
         URI uri = uri(namespace, path);
 
         List<URI> result = new ArrayList<>();
-        List<FileAttributes> list = storageInterface.list(tenantId, uri);
+        List<FileAttributes> list;
+        try {
+            list = storageInterface.list(tenantId, uri);
+        } catch (FileNotFoundException e) {
+            // prevent crashing upon trying to inject namespace files while the root namespace files folder doesn't exist
+            return result;
+        }
 
         for (var file: list) {
             URI current = URI.create((path != null ? path.getPath() : "") +  "/" + file.getFileName());


Test patch:
diff --git a/core/src/test/java/io/kestra/core/runners/NamespaceFilesServiceTest.java b/core/src/test/java/io/kestra/core/runners/NamespaceFilesServiceTest.java
index 232e63acae..d088159940 100644
--- a/core/src/test/java/io/kestra/core/runners/NamespaceFilesServiceTest.java
+++ b/core/src/test/java/io/kestra/core/runners/NamespaceFilesServiceTest.java
@@ -168,6 +168,22 @@ public void tenant() throws Exception {
         assertThat(content, is("2"));
     }
 
+    @Test
+    public void nsFilesRootFolderDoesntExist() throws Exception {
+        RunContext runContext = runContextFactory.of();
+        List<URI> injected = namespaceFilesService.inject(
+            runContextFactory.of(),
+            "tenant1",
+            "io.kestra." + IdUtils.create(),
+            runContext.tempDir(),
+            NamespaceFiles
+                .builder()
+                .enabled(true)
+                .build()
+        );
+        assertThat(injected.size(), is(0));
+    }
+
     private void put(@Nullable String tenantId, String namespace, String path, String content) throws IOException {
         storageInterface.put(
             tenantId,