pentaho/pentaho-kettle · error · KettleException

ZipFile.Error.TargetFileEmpty

Error message

ZipFile.Error.TargetFileEmpty

What it means

The dynamic zip target filename read from the current row is null or empty. The step logs 'ZipFile.Error.TargetFileEmpty' and throws a KettleException because there is no name for the zip archive to create.

Solutions

  1. Fix the upstream step to always supply a non-empty target filename.
  2. Filter out rows with empty target filenames before ZipFile.
  3. Substitute a computed default target filename when the value is empty.
  4. Confirm the correct field is configured as the dynamic target filename field.

Example fix

// before: rows with NULL zipTarget reach ZipFile
// after: Filter rows step
// condition: zipTarget IS NOT NULL AND LENGTH(zipTarget) > 0
Defensive patterns

Strategy: validation

Validate before calling

// Upstream filter before ZipFile:
// condition: zipTarget IS NOT NULL AND LENGTH(TRIM(zipTarget)) > 0

Try / catch

try {
  transformation.execute();
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("TargetFileEmpty")) {
    log.warn("Row skipped: empty zip target filename", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: getInputRowMeta().getString(r, data.indexOfZipFilename) returns null/empty at ZipFile.java:188 for a row (after the first-row field-index checks passed).

Common situations: A generator or lookup step emitted rows where the target filename is NULL; date/variable substitution produced an empty string; wrong field selected as the dynamic target filename field.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/zipfile/ZipFile.java:188

        data.baseFolder = getInputRowMeta().getString( r, data.indexOfBaseFolder );
      }

      // get destination folder
      String moveToFolder = null;
      if ( data.indexOfMoveToFolder > -1 ) {
        moveToFolder = getInputRowMeta().getString( r, data.indexOfMoveToFolder );
        if ( Utils.isEmpty( moveToFolder ) ) {
          throw new KettleException( BaseMessages.getString( PKG, "ZipFile.Error.EmptyMoveToFolder" ) );
        }
      }

      if ( !skip ) {
        // get value for target filename
        String targetFilename = getInputRowMeta().getString( r, data.indexOfZipFilename );

        if ( Utils.isEmpty( targetFilename ) ) {
          log.logError( toString(), BaseMessages.getString( PKG, "ZipFile.Error.TargetFileEmpty" ) );
          throw new KettleException( BaseMessages.getString( PKG, "ZipFile.Error.TargetFileEmpty" ) );
        }
        data.zipFile = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( targetFilename, this );
        if ( data.zipFile.exists() ) {
          if ( log.isDetailed() ) {
            log.logDetailed( toString(), BaseMessages.getString(
              PKG, "ZipFile.Log.TargetFileExists", targetFilename ) );
          }
        } else {
          // let's check parent folder
          FileObject parentFolder = data.zipFile.getParent();
          if ( !parentFolder.exists() ) {
            if ( !meta.isCreateParentFolder() ) {
              // Parent folder not exist
              // So we will fail
              throw new KettleException( BaseMessages.getString(
                PKG, "ZipFile.Error.TargetParentFolderNotExists", parentFolder.toString() ) );
            } else {
              // Create parent folder

View on GitHub (pinned to f3058517a1)