pentaho/pentaho-kettle · error · KettleValueException

: I don't know how to convert binary values to numbers.

Error message

 : I don't know how to convert binary values to numbers.

What it means

ValueMetaBase.getNumber() throws this KettleValueException when the value metadata has type TYPE_BINARY, because there is no defined conversion from a raw byte[] payload to a Double number. Pentaho Kettle (PDI) simply refuses to guess a numeric interpretation of opaque binary data. You must decode the bytes yourself (e.g. to a String or numeric type) before requesting a Number.

Solutions

  1. Change the field's value metadata type from TYPE_BINARY to a convertible type (TYPE_STRING or TYPE_INTEGER) using a 'Select values' / Metadata step or a new ValueMeta before calling getNumber().
  2. Convert the byte[] manually first (e.g. new ValueMetaString(...).convertBinaryStringToNativeType(bytes) or decode to a String/Integer) and then request the Number.
  3. If the column is genuinely opaque binary, do not call getNumber(); store/pass it as byte[] and only derive numeric values (length, checksum) explicitly.
  4. Catch KettleValueException and log/skip the field if binary data in a numeric context is acceptable.

Example fix

// before
ValueMetaInterface meta = new ValueMetaBase("blob", ValueMetaInterface.TYPE_BINARY);
Double n = meta.getNumber(rowData[0]); // throws

// after
ValueMetaInterface meta = new ValueMetaBase("blob", ValueMetaInterface.TYPE_STRING);
Double n = meta.getNumber(meta.convertBinaryStringToNativeType((byte[]) rowData[0]));
Defensive patterns

Strategy: type-guard

Validate before calling

if (meta.getType() == ValueMetaInterface.TYPE_BINARY) {
  throw new IllegalArgumentException("Field '" + meta.getName() + "' is BINARY; convert to String/Integer before getNumber()");
}

Type guard

boolean isNumberConvertible(ValueMetaInterface m) {
  int t = m.getType();
  return t == ValueMetaInterface.TYPE_STRING || t == ValueMetaInterface.TYPE_INTEGER
      || t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_BIGNUMBER
      || t == ValueMetaInterface.TYPE_BOOLEAN || t == ValueMetaInterface.TYPE_DATE;
}

Try / catch

try {
  Double n = meta.getNumber(value);
} catch (KettleValueException e) {
  log.warn("Cannot convert " + meta.getName() + " (binary) to Number", e);
}

Prevention

When it happens

Trigger: Calling ValueMeta.getNumber(Object) (or row.getNumber()/getRow with conversion) on a field whose valueMeta.getType() == ValueMetaInterface.TYPE_BINARY and whose data is a byte[].

Common situations: Reading binary columns from databases or files (BLOB, images, PDFs) and asking for them as numbers; misconfigured CSV/text input steps that set the field type to Binary instead of String/Number; custom transformation code that copies row data into Number-typed targets without changing the metadata type.

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

Appendix: source

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

              return new Double( ( (BigDecimal) convertBinaryStringToNativeType( (byte[]) object ) ).doubleValue() );
            case STORAGE_TYPE_INDEXED:
              return new Double( ( (BigDecimal) index[( (Integer) object ).intValue()] ).doubleValue() );
            default:
              throw new KettleValueException( toString() + " : Unknown storage type " + storageType + " specified." );
          }
        case TYPE_BOOLEAN:
          switch ( storageType ) {
            case STORAGE_TYPE_NORMAL:
              return convertBooleanToNumber( (Boolean) object );
            case STORAGE_TYPE_BINARY_STRING:
              return convertBooleanToNumber( (Boolean) convertBinaryStringToNativeType( (byte[]) object ) );
            case STORAGE_TYPE_INDEXED:
              return convertBooleanToNumber( (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 numbers." );
        case TYPE_SERIALIZABLE:
          throw new KettleValueException( toString() + " : I don't know how to convert serializable values to numbers." );
        default:
          throw new KettleValueException( toString() + " : Unknown type " + type + " specified." );
      }
    } catch ( Exception e ) {
      throw new KettleValueException( "Unexpected conversion error while converting value [" + toString()
          + "] to a Number", e );
    }
  }

  @Override
  public Long getInteger( Object object ) throws KettleValueException {
    try {
      if ( isNull( object ) ) {
        return null;
      }
      switch ( type ) {

View on GitHub (pinned to f3058517a1)