pentaho/pentaho-kettle · error · KettleException

This directory is not empty!

Error message

This directory is not empty!

What it means

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.

Solutions

  1. Pass deleteNonEmptyFolder=true only if recursive deletion is intended (destructive)
  2. First delete or move all transformations, jobs, and subdirectories inside it, then retry with false
  3. Check contents beforehand via repository.getJobNames/getTransformationNames(dir) and getSubDirectoryIDs
  4. Ask the user to confirm before enabling recursive delete

Example fix

// before
repository.delRepositoryDirectory( dir, false ); // throws if not empty
// after
if ( repository.getJobNames( dir, false ).length == 0
  && repository.getTransformationNames( dir, false ).length == 0
  && repository.getDirectoryIDs( dir.getObjectId() ).length == 0 ) {
  repository.delRepositoryDirectory( dir, false );
}
Defensive patterns

Strategy: validation

Validate before calling

boolean isEmptyDir = repository.getJobNames( dir, false ).length == 0
  && repository.getTransformationNames( dir, false ).length == 0
  && repository.getSubDirectoryIDs( dir.getObjectId() ).length == 0;
if ( !isEmptyDir && !forceRecursiveDelete ) {
  // abort: refuse to delete a non-empty folder
}

Try / catch

try {
  repository.delRepositoryDirectory( dir, false );
} catch ( KettleException e ) {
  if ( "This directory is not empty!".equals( e.getMessage() ) ) {
    // enumerate and delete children first, or require explicit confirmation
  }
}

Prevention

When it happens

Trigger: repository.delRepositoryDirectory(dir, false) invoked on a folder that still holds any transformations, jobs, or child directories.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/b26df2a03a0a4d33. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryDirectoryDelegate.java:318

      repository.commit();
    } catch ( Exception e ) {
      throw new KettleException( "Unable to save directory [" + dir + "] in the repository", e );
    }
  }

  public void delRepositoryDirectory( RepositoryDirectoryInterface dir, boolean deleteNonEmptyFolder ) throws KettleException {
    try {
      if ( !deleteNonEmptyFolder ) {
        String[] trans = repository.getTransformationNames( dir.getObjectId(), false ); // TODO : include or exclude
                                                                                        // deleted objects?
        String[] jobs = repository.getJobNames( dir.getObjectId(), false ); // TODO : include or exclude deleted
                                                                            // objects?
        ObjectId[] subDirectories = repository.getSubDirectoryIDs( dir.getObjectId() );
        if ( trans.length == 0 && jobs.length == 0 && subDirectories.length == 0 ) {
          repository.directoryDelegate.deleteDirectory( dir.getObjectId() );
          repository.commit();
        } else {
          throw new KettleException( "This directory is not empty!" );
        }
      } else {
        repository.directoryDelegate.deleteDirectory( dir );
        repository.commit();
      }
    } catch ( Exception e ) {
      throw new KettleException( "Unexpected error deleting repository directory:", e );
    }
  }

  /**
   * @deprecated use {@link #renameRepositoryDirectory(ObjectId, RepositoryDirectoryInterface, String)}
   *
   * @param dir
   * @return
   * @throws KettleException
   */
  @Deprecated

View on GitHub (pinned to f3058517a1)