pentaho/pentaho-kettle · error · KettleValueException

Unexpected conversion error while converting value [" +…

Error message

Unexpected conversion error while converting value [" + toString() + "] to an Integer

What it means

This is the catch-all wrapper in ValueMetaBase.getInteger(): any Exception thrown while converting the value to a Long (typically ClassCastException, NullPointerException on casts, or NumberFormatException inside converters) is rethrown as KettleValueException 'Unexpected conversion error while converting value [<meta>] to an Integer' with the original as cause. It means the stored object's runtime class did not match what the metadata type/storage type promised.

Solutions

  1. Inspect the cause chain (KettleValueException.getCause()) to see the real ClassCastException/NumberFormatException
  2. Make the value's runtime class match the metadata: use meta.convertData(sourceMeta, data) or write the value via the correct typed meta
  3. Normalize incoming data with a 'Value Mapper'/'Fieldtype change' or call ValueDataUtil / StringMeta conversion before numeric access
  4. If data comes from text, declare the field TYPE_STRING with STORAGE_TYPE_BINARY_STRING so Kettle parses it lazily with the conversion mask

Example fix

// before
// row field declared Long (TYPE_INTEGER) but contains String "123"
Long n = valueMeta.getInteger(row[i]); // ClassCastException -> wrapped
// after
ValueMetaInterface stringMeta = new ValueMetaString("col");
row[i] = valueMeta.convertData(stringMeta, row[i]); // parse string to Long
Long n = valueMeta.getInteger(row[i]);
Defensive patterns

Strategy: try-catch

Validate before calling

// verify runtime type matches declared metadata before converting
if (object != null && meta.getType() == ValueMetaInterface.TYPE_INTEGER
    && !(object instanceof Long)) {
  object = meta.convertData(new ValueMetaString(meta.getName()), object); // coerce
}

Type guard

boolean matchesDeclaredType(ValueMetaInterface m, Object v) {
  if (v == null) return true;
  switch (m.getType()) {
    case ValueMetaInterface.TYPE_INTEGER: return v instanceof Long;
    case ValueMetaInterface.TYPE_NUMBER: return v instanceof Double;
    case ValueMetaInterface.TYPE_BIGNUMBER: return v instanceof java.math.BigDecimal;
    case ValueMetaInterface.TYPE_STRING: return v instanceof String;
    case ValueMetaInterface.TYPE_DATE: return v instanceof java.util.Date;
    case ValueMetaInterface.TYPE_BOOLEAN: return v instanceof Boolean;
    default: return true;
  }
}

Try / catch

try {
  Long n = meta.getInteger(object);
} catch (KettleValueException e) {
  Throwable cause = e.getCause();
  log.error("Conversion failed for " + meta.getName() + ": "
      + (cause != null ? cause.toString() : e.getMessage()));
  // send row to error stream
}

Prevention

When it happens

Trigger: Any mismatch between the object's actual runtime type and the metadata's declared type/storage type inside getInteger(Object): e.g. a String stored under TYPE_INTEGER+STORAGE_TYPE_NORMAL, a byte[] not decoded where expected, or an indexed storage value of wrong element type. Check getCause() for the real exception.

Common situations: Steps writing raw strings into nominally numeric fields; data migrated from CSV/database steps without proper conversion metadata; plugins that construct rows manually without respecting rowMeta 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/4b9ad0b8133949cf. Report an issue: GitHub.

Appendix: source

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

            case STORAGE_TYPE_NORMAL:
              return convertBooleanToInteger( (Boolean) object );
            case STORAGE_TYPE_BINARY_STRING:
              return convertBooleanToInteger( (Boolean) convertBinaryStringToNativeType( (byte[]) object ) );
            case STORAGE_TYPE_INDEXED:
              return convertBooleanToInteger( (Boolean) index[( (Integer) object ).intValue()] );
            default:
              throw new KettleValueException( toString() + " : Unknown storage type " + storageType + " specified." );
          }
        case TYPE_BINARY:
          throw new KettleValueException( toString() + " : I don't know how to convert binary values to integers." );
        case TYPE_SERIALIZABLE:
          throw new KettleValueException( toString()
              + " : I don't know how to convert serializable values to integers." );
        default:
          throw new KettleValueException( toString() + " : Unknown type " + type + " specified." );
      }
    } catch ( Exception e ) {
      throw new KettleValueException( "Unexpected conversion error while converting value [" + toString()
          + "] to an Integer", e );
    }
  }

  @Override
  public BigDecimal getBigNumber( Object object ) throws KettleValueException {
    try {
      if ( isNull( object ) ) {
        return null;
      }
      switch ( type ) {
        case TYPE_BIGNUMBER:
          switch ( storageType ) {
            case STORAGE_TYPE_NORMAL:
              return (BigDecimal) object;
            case STORAGE_TYPE_BINARY_STRING:
              return (BigDecimal) convertBinaryStringToNativeType( (byte[]) object );
            case STORAGE_TYPE_INDEXED:

View on GitHub (pinned to f3058517a1)