pentaho/pentaho-kettle · error · KettleValueException

: There was a data type error: the data type of " +…

Error message

 : 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

Thrown by ValueMetaBase.getString(Object) when the underlying Java object does not match the value meta's declared type: the per-type switch performed an illegal cast (caught ClassCastException) and is rethrown as a KettleValueException naming both the object's actual class and the expected metadata. It means row data and row metadata disagree.

Solutions

  1. Align row metadata with actual data: regenerate RowMeta for the stream (e.g. setInputRowMeta from real row layout)
  2. Convert the value explicitly first: ValueDataUtil or valueMeta.convertData(expectedMeta, object)
  3. Inspect the exception text — it prints the object's class vs toStringMeta() — and fix the step producing the mismatched field

Example fix

// before
// meta declares TYPE_INTEGER but value is a String
String s = valueMeta.getInteger( "123" ); // throws
// after
Object converted = valueMeta.convertData( new ValueMetaString( "col" ), rawValue );
String s = valueMeta.getString( converted );
Defensive patterns

Strategy: try-catch

Validate before calling

Object v = row[dataIndex];
if ( meta.isInteger() && !( v instanceof Long || v == null ) ) {
  v = Long.valueOf( v.toString() );
}

Type guard

boolean matchesMeta( ValueMetaInterface m, Object v ) {
  if ( v == null ) return true;
  if ( m.isString() ) return v instanceof String;
  if ( m.isInteger() ) return v instanceof Long;
  if ( m.isNumber() ) return v instanceof Double;
  if ( m.isBigNumber() ) return v instanceof java.math.BigDecimal;
  if ( m.isDate() ) return v instanceof java.util.Date;
  if ( m.isBoolean() ) return v instanceof Boolean;
  if ( m.isBinary() ) return v instanceof byte[];
  return true;
}

Try / catch

try { return meta.getString( value ); }
catch ( KettleValueException e ) {
  log.error( "Row/meta mismatch: {}", e.getMessage() );
  return meta.getString( meta.convertData( new ValueMetaString( meta.getName() ), value ) );
}

Prevention

When it happens

Trigger: Calling getString() on a row value whose runtime class differs from the meta (e.g. meta says TYPE_INTEGER (Long) but the field holds a String or BigDecimal; or a storageType of INDEXED where object is not an Integer index).

Common situations: Steps that write rows without creating matching row metadata (RowMetaAndData misuse); mixing rows from two different row sets after a join/merge; changing a field type upstream without adjusting downstream metadata; hand-populating Object[] rows.

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/e785cd36cd52047d. Report an issue: GitHub.

Appendix: source

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

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

        default:
          throw new KettleValueException( toString() + " : Unknown type " + type + " specified." );
      }

      if ( isOutputPaddingEnabled() && getLength() > 0 ) {
        string = ValueDataUtil.rightPad( string, getLength() );
      }

      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() + "]" );
    }
  }

  protected String trim( String string ) {
    switch ( getTrimType() ) {
      case TRIM_TYPE_NONE:
        break;
      case TRIM_TYPE_RIGHT:
        string = Const.rtrim( string );
        break;
      case TRIM_TYPE_LEFT:
        string = Const.ltrim( string );
        break;
      case TRIM_TYPE_BOTH:
        string = Const.trim( string );
        break;

View on GitHub (pinned to f3058517a1)