pentaho/pentaho-kettle · error · KettleValueException

<toString()> : There was a data type error: the data type…

Error message

<toString()> : There was a data type error: the data type of <object.getClass().getName()> object [<object>] does not correspond to value meta [<toStringMeta()>]

What it means

ValueMetaBase catches ClassCastException during string conversion and rethrows it as KettleValueException naming both the actual Java class of the data object and the expected value meta description. This is the classic Kettle type-mismatch error: the ValueDataInterface stored in the row does not match what the metadata promises (e.g. a String stored where the meta says Date, or an index Integer with NORMAL storage).

Solutions

  1. Align the row metadata with the actual data: rebuild RowMetaInterface via RowMetaAndData or the step's getFields() so declared types match stored objects
  2. Convert explicitly before conversion: use ValueDataUtil or ValueMeta.convertData(...) to coerce the object to the meta type
  3. If data is indexed, ensure storageType is STORAGE_TYPE_INDEXED and the object is an Integer index; otherwise use STORAGE_TYPE_NORMAL with the native object
  4. Log object.getClass() against meta.toStringMeta() at the producing step to locate where types diverge

Example fix

// before
Object v = row[i]; // actually a String
String s = dateMeta.toString(v); // throws KettleValueException
// after
String s = dateMeta.toString(
    dateMeta.convertData(new ValueMetaString("tmp"), v));
Defensive patterns

Strategy: type-guard

Validate before calling

// before conversion, verify the runtime type matches the meta type
if (meta.getType() == ValueMetaInterface.TYPE_DATE && !(data instanceof java.util.Date)) {
  data = meta.convertData(new ValueMetaString("tmp"), String.valueOf(data));
}

Type guard

boolean matchesMetaType(ValueMetaInterface meta, Object data) {
  if (data == null) return true;
  switch (meta.getType()) {
    case ValueMetaInterface.TYPE_STRING: return data instanceof String;
    case ValueMetaInterface.TYPE_DATE: return data instanceof java.util.Date;
    case ValueMetaInterface.TYPE_NUMBER: return data instanceof Double;
    case ValueMetaInterface.TYPE_INTEGER: return data instanceof Long;
    case ValueMetaInterface.TYPE_BIGNUMBER: return data instanceof java.math.BigDecimal;
    case ValueMetaInterface.TYPE_BOOLEAN: return data instanceof Boolean;
    case ValueMetaInterface.TYPE_BINARY: return data instanceof byte[];
    default: return true;
  }
}

Try / catch

try {
  String s = meta.toString(data);
} catch (KettleValueException e) {
  logError("Type mismatch: " + (data == null ? "null" : data.getClass().getName())
      + " for meta " + meta.toStringMeta());
  // convert or skip the row
  data = meta.convertData(new ValueMetaString("tmp"), String.valueOf(data));
  String s = meta.toString(data);
}

Prevention

When it happens

Trigger: Calling getString()/toString() when the row object's runtime class doesn't match the meta type: e.g. TYPE_DATE meta receiving a java.lang.String, STORAGE_TYPE_NORMAL meta receiving an Integer index (indexed data), or TYPE_STRING meta receiving a Double.

Common situations: Mixing rows from different sources/steps whose RowMeta differs; incorrect index[] metadata with STORAGE_TYPE_INDEXED; mapping database columns with wrong conversion; passing raw Object[] between transformations without re-converting types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:1781

              }
              break;
            case STORAGE_TYPE_INDEXED:
              string =
                  object == null ? null : convertIntegerToCompatibleString( (Long) index[( (Integer) object )
                      .intValue()] );
              break;
            default:
              throw new KettleValueException( toString() + " : Unknown storage type " + storageType + " specified." );
          }
          break;

        default:
          return getString( object );
      }

      return string;
    } catch ( ClassCastException e ) {
      throw new KettleValueException( toString() + " : There was a data type error: the data type of "
          + object.getClass().getName() + " object [" + object + "] does not correspond to value meta ["
          + toStringMeta() + "]" );
    }
  }

  @Override
  public String getString( Object object ) throws KettleValueException {
    try {
      String string;

      switch ( type ) {
        case TYPE_STRING:
          switch ( storageType ) {
            case STORAGE_TYPE_NORMAL:
              string = object == null ? null : object.toString();
              break;
            case STORAGE_TYPE_BINARY_STRING:
              string = (String) convertBinaryStringToNativeType( (byte[]) object );

View on GitHub (pinned to f3058517a1)