pentaho/pentaho-kettle · error · KettleException

ZipFile.Error.EmptyMoveToFolder

Error message

ZipFile.Error.EmptyMoveToFolder

What it means

With operation MOVE, the move-to-folder field is present in the row but its value for the current row is null or empty. The step throws this KettleException because it cannot decide where to move the zipped file for that row.

Solutions

  1. Fix the upstream step so every row carries a valid destination folder value.
  2. Add a Filter rows step routing rows with an empty move-to-folder value elsewhere.
  3. Use an NVL/default-value step to substitute a fallback folder.
  4. Verify the correct field is selected as the move-to-folder field.

Example fix

// before: moveFolder may be null
// after: default it upstream
NVL(moveToFolder, "/data/archive") // via 'Value Mapper' or calculator/default step
Defensive patterns

Strategy: validation

Validate before calling

// Upstream filter/default for the move-to-folder column:
// condition: moveToFolder IS NOT NULL AND TRIM(moveToFolder) <> ""
// or default: NVL(moveToFolder, "/data/archive")

Try / catch

try {
  transformation.execute();
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("EmptyMoveToFolder")) {
    log.warn("Row skipped: empty move-to-folder value", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: data.indexOfMoveToFolder > -1 and getInputRowMeta().getString(r, data.indexOfMoveToFolder) returns null/empty at ZipFile.java:178 during per-row processing (not first-row init).

Common situations: Upstream lookup or calculation produced NULL for some rows only; a text input row with a missing column; a join left the destination folder blank for unmatched rows.

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/5b6d34b168a7df18. Report an issue: GitHub.

Appendix: source

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

        if ( data.sourceFile.getType() != FileType.FILE ) {
          log.logError( toString(), BaseMessages
            .getString( PKG, "ZipFile.Error.SourceFileNotFile", sourceFilename ) );
          throw new KettleException( BaseMessages.getString(
            PKG, "ZipFile.Error.SourceFileNotFile", sourceFilename ) );
        }
      }

      // get basefolder
      if ( data.indexOfBaseFolder > -1 ) {
        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 {

View on GitHub (pinned to f3058517a1)