{"record":{"id":"90e9de758c5c848a","repo":"pentaho/pentaho-kettle","slug":"i-don-t-know-how-to-convert-a-serializable-value-to","errorCode":null,"errorMessage":" : I don't know how to convert a serializable value to timestamp.","messagePattern":" : I don't know how to convert a serializable value to timestamp\\.","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/value/ValueMetaTimestamp.java","lineNumber":190,"sourceCode":"            throw new KettleValueException( toString() + \" : Unknown storage type \" + storageType + \" specified.\" );\n        }\n      case TYPE_BIGNUMBER:\n        switch ( storageType ) {\n          case STORAGE_TYPE_NORMAL:\n            return convertBigNumberToTimestamp( (BigDecimal) object );\n          case STORAGE_TYPE_BINARY_STRING:\n            return convertBigNumberToTimestamp( (BigDecimal) convertBinaryStringToNativeType( (byte[]) object ) );\n          case STORAGE_TYPE_INDEXED:\n            return convertBigNumberToTimestamp( (BigDecimal) index[ ( (Integer) object ).intValue() ] );\n          default:\n            throw new KettleValueException( toString() + \" : Unknown storage type \" + storageType + \" specified.\" );\n        }\n      case TYPE_BOOLEAN:\n        throw new KettleValueException( toString() + \" : I don't know how to convert a boolean to a timestamp.\" );\n      case TYPE_BINARY:\n        throw new KettleValueException( toString() + \" : I don't know how to convert a binary value to timestamp.\" );\n      case TYPE_SERIALIZABLE:\n        throw new KettleValueException( toString()\n          + \" : I don't know how to convert a serializable value to timestamp.\" );\n\n      default:\n        throw new KettleValueException( toString() + \" : Unknown type \" + type + \" specified.\" );\n    }\n  }\n\n  public int compare( Object data1, Object data2 ) throws KettleValueException {\n    Timestamp timestamp1 = getTimestamp( data1 );\n    Timestamp timestamp2 = getTimestamp( data2 );\n    int cmp = 0;\n    if ( timestamp1 == null ) {\n      if ( timestamp2 == null ) {\n        cmp = 0;\n      } else {\n        cmp = -1;\n      }\n    } else if ( timestamp2 == null ) {","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/value/ValueMetaTimestamp.java#L172-L208","documentation":"getTimestamp() has no conversion defined for TYPE_SERIALIZABLE source values and throws this KettleValueException unconditionally for that case. Serializable-typed fields (arbitrary Java objects passed between steps) cannot be interpreted as timestamps by the generic value-meta machinery.","triggerScenarios":"Calling getTimestamp(object) on a ValueMetaTimestamp whose type is TYPE_SERIALIZABLE — i.e. the field holds a serialized Java object rather than a scalar convertible type.","commonSituations":"User-defined Java classes flowing through rows (e.g. from UDJC steps) later read as timestamps; metadata where the type defaulted to SERIALIZABLE because the plugin never set a concrete type; mapping fields between transformations with mismatched type declarations.","solutions":["Give the field a concrete type (TYPE_DATE/TYPE_TIMESTAMP or TYPE_STRING) instead of TYPE_SERIALIZABLE when its values are timestamps.","If the object truly is a timestamp holder, extract it explicitly: Timestamp t = (Timestamp) ((MyHolder) object).getValue(); and skip the value-meta conversion.","Set the metadata type in the producing step (meta.setType(ValueMetaInterface.TYPE_TIMESTAMP)) so downstream getTimestamp() uses the supported path.","In generic row-processing code, check meta.getType() and skip TYPE_SERIALIZABLE fields rather than attempting conversion."],"exampleFix":"// before\nValueMeta meta = new ValueMeta( \"obj\", ValueMetaInterface.TYPE_SERIALIZABLE );\nTimestamp t = meta.getTimestamp( object ); // throws\n// after\nValueMeta meta = new ValueMeta( \"obj\", ValueMetaInterface.TYPE_TIMESTAMP );\nTimestamp t = meta.getTimestamp( object ); // uses STORAGE_TYPE_NORMAL path","handlingStrategy":"type-guard","validationCode":"if ( meta.getType() == ValueMetaInterface.TYPE_SERIALIZABLE ) {\n  // extract the object yourself; getTimestamp() will throw\n}","typeGuard":"boolean isTimestampConvertible( ValueMetaInterface meta ) {\n  switch ( meta.getType() ) {\n    case ValueMetaInterface.TYPE_TIMESTAMP:\n    case ValueMetaInterface.TYPE_DATE:\n    case ValueMetaInterface.TYPE_STRING:\n    case ValueMetaInterface.TYPE_NUMBER:\n    case ValueMetaInterface.TYPE_INTEGER:\n    case ValueMetaInterface.TYPE_BIGNUMBER:\n      return true;\n    default:\n      return false;\n  }\n}","tryCatchPattern":"try {\n  t = meta.getTimestamp( value );\n} catch ( KettleValueException e ) {\n  if ( e.getMessage().contains( \"convert a serializable value to timestamp\" ) ) {\n    t = ( value instanceof Timestamp ) ? (Timestamp) value : null;\n  } else { throw e; }\n}","preventionTips":["Set a concrete type (TYPE_TIMESTAMP/TYPE_STRING) instead of TYPE_SERIALIZABLE for timestamp-bearing fields.","In UDJC or plugin steps, always assign an explicit value-meta type to output fields.","Skip SERIALIZABLE fields in generic conversion loops.","Cast to Timestamp directly when you know the serialized object's runtime type."],"tags":["kettle","pdi","type-conversion","timestamp","serializable"],"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"}