{"record":{"id":"2d7f0fa9ed9fdf10","repo":"pentaho/pentaho-kettle","slug":"clone-not-supported-for","errorCode":null,"errorMessage":"Clone not supported for ","messagePattern":"Clone not supported for ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/file/BaseFileErrorHandling.java","lineNumber":68,"sourceCode":"\n  /** The extension of error files */\n  @Injection( name = \"ERROR_FILES_EXTENTION\" )\n  public String errorFilesExtension;\n\n  /** The directory that will contain line number files */\n  @Injection( name = \"LINE_NR_FILES_TARGET_DIR\" )\n  public String lineNumberFilesDestinationDirectory;\n\n  /** The extension of line number files */\n  @Injection( name = \"LINE_NR_FILES_EXTENTION\" )\n  public String lineNumberFilesExtension;\n\n  @Override\n  public Object clone() {\n    try {\n      return super.clone();\n    } catch ( CloneNotSupportedException ex ) {\n      throw new IllegalArgumentException( \"Clone not supported for \" + this.getClass().getName() );\n    }\n  }\n}\n","sourceCodeStart":50,"sourceCodeEnd":72,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/file/BaseFileErrorHandling.java#L50-L72","documentation":"BaseFileErrorHandling.clone() calls super.clone(); if the class (or a subclass) does not implement Cloneable, the JVM throws CloneNotSupportedException, which this code converts into an IllegalArgumentException naming the offending class. This is a programming/invariant error, not expected runtime input.","triggerScenarios":"Subclassing BaseFileErrorHandling (or adding a non-cloneable field type that breaks Cloneable semantics) and having PDI clone the step's error-handling settings object without the class being Cloneable.","commonSituations":"Custom step development extending base file handling classes but forgetting to implement Cloneable; refactoring that removed Cloneable from the hierarchy.","solutions":["Add `implements Cloneable` to the offending class (the name is in the exception message)","Ensure the default Object.clone() shallow copy is acceptable; deep-clone mutable fields if needed","Alternatively, implement clone() manually without relying on super.clone()"],"exampleFix":"// before\nclass BaseFileErrorHandling { ... }\n// after\nclass BaseFileErrorHandling implements Cloneable { ... }","handlingStrategy":"try-catch","validationCode":"if (!(obj instanceof BaseFileErrorHandling && obj instanceof Cloneable)) {\n  throw new IllegalArgumentException(\"Not cloneable: \" + obj.getClass().getName());\n}","typeGuard":"boolean isCloneable(Object o) { return o instanceof Cloneable; }","tryCatchPattern":"try { copy = errorHandling.clone(); }\ncatch (IllegalArgumentException e) {\n  log.error(\"Clone unsupported: {}\", e.getMessage());\n  copy = new BaseFileErrorHandling(); // construct a fresh instance instead\n}","preventionTips":["Always declare `implements Cloneable` when overriding clone()","Deep-copy mutable fields in clone() for custom step subclasses","Unit-test clone() on custom step meta classes"],"tags":["pdi","clone","custom-steps"],"backgroundTag":"unsupported-operation","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"}