{"record":{"id":"1fd24ad15d493825","repo":"pentaho/pentaho-kettle","slug":"unexpected-error-deleting-repository-directory","errorCode":null,"errorMessage":"Unexpected error deleting repository directory:","messagePattern":"Unexpected error deleting repository directory:","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryDirectoryDelegate.java","lineNumber":325,"sourceCode":"    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\n  public ObjectId renameRepositoryDirectory( RepositoryDirectory dir ) throws KettleException {\n    try {\n      renameDirectory( dir.getObjectId(), null, dir.getName() );\n      return dir.getObjectId(); // doesn't change in this specific case.\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unable to rename the specified repository directory [\" + dir + \"]\", e );\n    }","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryDirectoryDelegate.java#L307-L343","documentation":"Generic wrapper KettleException thrown by delRepositoryDirectory for any exception raised while deleting a directory (including failures in the delete/commit calls themselves). Unlike the 'not empty' guard, this wraps unexpected errors: database failures, rollback issues, or errors from directoryDelegate.deleteDirectory. The cause carries the actual problem.","triggerScenarios":"delRepositoryDirectory(dir, deleteNonEmptyFolder) where the deleteDirectory DB call, repository.commit(), or a nested recursive deletion fails: connection loss, foreign-key constraints, permission issues on the repository tables.","commonSituations":"Repository RDBMS connection dropped mid-delete; foreign-key rows in dependent tables blocking deletion; another client concurrently modifying the directory; insufficient DB user privileges to delete rows.","solutions":["Inspect e.getCause() for the real SQLException and address it (connectivity, privileges, constraints)","Retry the deletion after restoring the repository connection","Check the repository DB user has DELETE privileges on r_directory and dependent tables","Delete or cascade-clean dependent rows (trans/jobs/subdirs) before deleting"],"exampleFix":"// before\nrepository.delRepositoryDirectory( dir, true );\n// after\ntry {\n  repository.delRepositoryDirectory( dir, true );\n} catch ( KettleException e ) {\n  log.error( \"Delete failed: \", e.getCause() ); // check DB connectivity/privileges, then retry\n}","handlingStrategy":"try-catch","validationCode":"// ensure DB reachable and user has DELETE rights before delete\nrepository.connect( ... ); // throws early if unreachable","typeGuard":null,"tryCatchPattern":"try {\n  repository.delRepositoryDirectory( dir, recursive );\n} catch ( KettleException e ) {\n  log.error( \"Directory delete failed\", e.getCause() );\n  // retry after reconnect; check DB privileges/constraints\n}","preventionTips":["Always inspect getCause(); the message itself carries no detail","Verify the repository DB user has DELETE privileges on r_directory and dependents","Retry transient connection failures with backoff","Delete dependent rows/children before the parent directory"],"tags":["database","directory-delete","transaction"],"backgroundTag":"database-write-failed","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"}