pentaho/pentaho-kettle · error · IllegalArgumentException

Clone not supported for

Error message

Clone not supported for 

What it means

BaseFileInputFiles.clone() performs a field-by-field shallow copy plus Arrays.copyOf for its String[]/boolean[] arrays, and wraps CloneNotSupportedException in an IllegalArgumentException when the concrete class is not Cloneable. Since the clone method itself is implemented here, the failure means the runtime class lacks the Cloneable marker interface.

Solutions

  1. Make the concrete class named in the message implement Cloneable.
  2. Rebuild/redeploy the plugin so the corrected class is on the classpath.
  3. If cloning persists, duplicate the object manually (new instance + Arrays.copyOf of each array).

Example fix

// before
public class MyFiles extends BaseFileInputFiles { }
// after
public class MyFiles extends BaseFileInputFiles implements Cloneable { }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Cloneable.class.isAssignableFrom(files.getClass())) {
  throw new IllegalStateException(files.getClass().getName() + " must implement Cloneable");
}

Type guard

boolean isCloneable(Object o) { return o instanceof Cloneable; }

Try / catch

try {
  BaseFileInputFiles copy = (BaseFileInputFiles) files.clone();
} catch (IllegalArgumentException e) {
  throw new IllegalStateException("Add Cloneable to " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Cloning a BaseFileInputFiles instance (file lists of a file-input step) whose concrete class does not implement Cloneable, typically during transformation copy or step metadata duplication.

Common situations: Custom file-input plugins extending BaseFileInputFiles without Cloneable; class-hierarchy changes across Pentaho/Kettle versions breaking metadata copy at design time or run time.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/file/BaseFileInputFiles.java:96

  @Injection( name = "ACCEPT_FILE_FIELD" )
  public String acceptingField;

  /** The add filenames to result filenames flag */
  @Injection( name = "ADD_FILES_TO_RESULT" )
  public boolean isaddresult;

  @Override
  public Object clone() {
    try {
      BaseFileInputFiles cloned = (BaseFileInputFiles) super.clone();
      cloned.fileName = Arrays.copyOf( fileName, fileName.length );
      cloned.fileMask = Arrays.copyOf( fileMask, fileMask.length );
      cloned.excludeFileMask = Arrays.copyOf( excludeFileMask, excludeFileMask.length );
      cloned.fileRequired = Arrays.copyOf( fileRequired, fileRequired.length );
      cloned.includeSubFolders = Arrays.copyOf( includeSubFolders, includeSubFolders.length );
      return cloned;
    } catch ( CloneNotSupportedException ex ) {
      throw new IllegalArgumentException( "Clone not supported for " + this.getClass().getName() );
    }
  }

  public void setFileRequired( String[] fileRequiredin ) {
    for ( int i = 0; i < fileRequiredin.length; i++ ) {
      this.fileRequired[i] = getRequiredFilesCode( fileRequiredin[i] );
    }
  }

  public void setIncludeSubFolders( String[] includeSubFoldersin ) {
    for ( int i = 0; i < includeSubFoldersin.length; i++ ) {
      this.includeSubFolders[i] = getRequiredFilesCode( includeSubFoldersin[i] );
    }
  }

  public static String getRequiredFilesCode( String tt ) {
    if ( tt == null ) {
      return RequiredFilesCode[0];

View on GitHub (pinned to f3058517a1)