{"record":{"id":"fe70f1bf0db6edb8","repo":"pentaho/pentaho-kettle","slug":"problem-with-clone-row-detected-in-rowmetaanddata","errorCode":null,"errorMessage":"Problem with clone row detected in RowMetaAndData","messagePattern":"Problem with clone row detected in RowMetaAndData","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/RowMetaAndData.java","lineNumber":57,"sourceCode":"  }\n\n  /**\n   * @param rowMeta\n   * @param data\n   */\n  public RowMetaAndData( RowMetaInterface rowMeta, Object... data ) {\n    this.rowMeta = rowMeta;\n    this.data = data;\n  }\n\n  @Override\n  public RowMetaAndData clone() {\n    RowMetaAndData c = new RowMetaAndData();\n    c.rowMeta = rowMeta.clone();\n    try {\n      c.data = rowMeta.cloneRow( data );\n    } catch ( KettleValueException e ) {\n      throw new RuntimeException( \"Problem with clone row detected in RowMetaAndData\", e );\n    }\n\n    return c;\n  }\n\n  @Override\n  public String toString() {\n    try {\n      return rowMeta.getString( data );\n    } catch ( KettleValueException e ) {\n      return rowMeta.toString() + \", error presenting data: \" + e.toString();\n    }\n  }\n\n  /**\n   * @return the data\n   */\n  public Object[] getData() {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/RowMetaAndData.java#L39-L75","documentation":"RowMetaAndData.clone() deep-copies the row metadata and data via rowMeta.cloneRow(data). If cloneRow raises KettleValueException (a data conversion problem cloning one of the value objects), the method converts it to a RuntimeException since Object.clone() cannot throw checked exceptions.","triggerScenarios":"Calling clone() on a RowMetaAndData whose row contains a value the row metadata cannot clone — e.g. binary value / custom data type inconsistent with its declared ValueMeta, or stale metadata after columns changed.","commonSituations":"Rows built manually with mismatched metadata vs actual value types, big decimal/date values with unusual converters, cloning rows inside plugin code after modifying rowMeta without adjusting data.","solutions":["Ensure rowMeta matches the actual value objects in data (rebuild RowMetaAndData if metadata changed)","Inspect the cause KettleValueException to identify which field fails conversion","Use safe conversions when building rows (ValueDataUtil / correct ValueMeta types)","Wrap clone in try-catch and copy the row field-by-field as a fallback"],"exampleFix":"// before\nRowMetaAndData copy = rowMetaAndData.clone();\n// after\nRowMetaAndData copy;\ntry {\n  copy = rowMetaAndData.clone();\n} catch (RuntimeException e) {\n  copy = manualCopy(rowMetaAndData); // field-by-field copy with ValueDataUtil\n}","handlingStrategy":"try-catch","validationCode":"// check metadata/data consistency before cloning\nfor (int i = 0; i < rmad.getRowMeta().size(); i++) {\n  Object v = rmad.getData()[i];\n  if (v != null && !rmad.getRowMeta().getValueMeta(i).getType()\n      .equals(ValueMetaFactory.getIdForValueMeta(v.getClass().getSimpleName())) ) { /* log mismatch */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n  RowMetaAndData copy = rmad.clone();\n} catch (RuntimeException e) {\n  Throwable cause = e.getCause(); // KettleValueException\n  // fall back to field-by-field copy\n}","preventionTips":["Keep rowMeta in sync with actual data values when building rows","Use correct ValueMeta types and converters at row construction time","Inspect getCause() (KettleValueException) to identify the offending field"],"tags":["clone","row-metadata","conversion","runtime"],"backgroundTag":"type-mismatch","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"}