{"record":{"id":"b26df2a03a0a4d33","repo":"pentaho/pentaho-kettle","slug":"this-directory-is-not-empty","errorCode":null,"errorMessage":"This directory is not empty!","messagePattern":"This directory is not empty!","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryDirectoryDelegate.java","lineNumber":318,"sourceCode":"      repository.commit();\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unable to save directory [\" + dir + \"] in the repository\", e );\n    }\n  }\n\n  public void delRepositoryDirectory( RepositoryDirectoryInterface dir, boolean deleteNonEmptyFolder ) throws KettleException {\n    try {\n      if ( !deleteNonEmptyFolder ) {\n        String[] trans = repository.getTransformationNames( dir.getObjectId(), false ); // TODO : include or exclude\n                                                                                        // deleted objects?\n        String[] jobs = repository.getJobNames( dir.getObjectId(), false ); // TODO : include or exclude deleted\n                                                                            // objects?\n        ObjectId[] subDirectories = repository.getSubDirectoryIDs( dir.getObjectId() );\n        if ( trans.length == 0 && jobs.length == 0 && subDirectories.length == 0 ) {\n          repository.directoryDelegate.deleteDirectory( dir.getObjectId() );\n          repository.commit();\n        } else {\n          throw new KettleException( \"This directory is not empty!\" );\n        }\n      } else {\n        repository.directoryDelegate.deleteDirectory( dir );\n        repository.commit();\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unexpected error deleting repository directory:\", e );\n    }\n  }\n\n  /**\n   * @deprecated use {@link #renameRepositoryDirectory(ObjectId, RepositoryDirectoryInterface, String)}\n   *\n   * @param dir\n   * @return\n   * @throws KettleException\n   */\n  @Deprecated","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryDirectoryDelegate.java#L300-L336","documentation":"Thrown by delRepositoryDirectory when deleteNonEmptyFolder is false but the directory still contains transformations, jobs, or subdirectories. The guard checks trans.length==0 && jobs.length==0 && subDirectories.length==0 and refuses to delete non-empty folders to prevent silent data loss. It is a deliberate precondition failure, not a database error.","triggerScenarios":"repository.delRepositoryDirectory(dir, false) invoked on a folder that still holds any transformations, jobs, or child directories.","commonSituations":"Users trying to prune a folder tree whose leaves were not cleaned first; automated cleanup scripts that assumed the folder was empty; UI operations where the folder still contains hidden or recently added items.","solutions":["Pass deleteNonEmptyFolder=true only if recursive deletion is intended (destructive)","First delete or move all transformations, jobs, and subdirectories inside it, then retry with false","Check contents beforehand via repository.getJobNames/getTransformationNames(dir) and getSubDirectoryIDs","Ask the user to confirm before enabling recursive delete"],"exampleFix":"// before\nrepository.delRepositoryDirectory( dir, false ); // throws if not empty\n// after\nif ( repository.getJobNames( dir, false ).length == 0\n  && repository.getTransformationNames( dir, false ).length == 0\n  && repository.getDirectoryIDs( dir.getObjectId() ).length == 0 ) {\n  repository.delRepositoryDirectory( dir, false );\n}","handlingStrategy":"validation","validationCode":"boolean isEmptyDir = repository.getJobNames( dir, false ).length == 0\n  && repository.getTransformationNames( dir, false ).length == 0\n  && repository.getSubDirectoryIDs( dir.getObjectId() ).length == 0;\nif ( !isEmptyDir && !forceRecursiveDelete ) {\n  // abort: refuse to delete a non-empty folder\n}","typeGuard":null,"tryCatchPattern":"try {\n  repository.delRepositoryDirectory( dir, false );\n} catch ( KettleException e ) {\n  if ( \"This directory is not empty!\".equals( e.getMessage() ) ) {\n    // enumerate and delete children first, or require explicit confirmation\n  }\n}","preventionTips":["Enumerate jobs/transformations/subdirectories before deleting","Only pass deleteNonEmptyFolder=true with explicit user confirmation","Clean up folder leaves before pruning parent folders in scripts"],"tags":["validation","directory-delete","precondition"],"backgroundTag":"invalid-state-transition","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}