pentaho/pentaho-kettle · error · KettleValueException

get zero function undefined for data type: <type.getType()>

Error message

get zero function undefined for data type: <type.getType()>

What it means

getZeroForValueMetaType switches over type.getType() and only knows the standard Kettle types (Integer, Number, Date, Boolean, BigNumber, String, etc.). A ValueMetaInterface whose concrete type constant has no case in the switch falls into the default branch and throws this KettleValueException naming the numeric type code.

Solutions

  1. Only call the function for supported types; pre-check with a switch/whitelist on type.getType() against ValueMetaInterface constants
  2. Add handling for the specific type yourself (e.g. return null or an empty byte[] for TYPE_BINARY) before calling
  3. If your Pentaho version lacks a case (e.g. TIMESTAMP), upgrade or compute the zero manually
  4. For custom ValueMeta plugins, register/implement zero-value semantics instead of relying on this utility

Example fix

// before
Object zero = ValueDataUtil.getZeroForValueMetaType( binaryMeta ); // TYPE_BINARY -> throws
// after
int t = binaryMeta.getType();
Object zero = ( t == ValueMetaInterface.TYPE_BINARY ) ? new byte[0]
  : ( t == ValueMetaInterface.TYPE_TIMESTAMP ) ? new java.sql.Timestamp( 0 )
  : ValueDataUtil.getZeroForValueMetaType( binaryMeta );
Defensive patterns

Strategy: validation

Validate before calling

int t = type.getType();
java.util.Set<Integer> supported = new HashSet<>( java.util.Arrays.asList(
  ValueMetaInterface.TYPE_INTEGER, ValueMetaInterface.TYPE_NUMBER, ValueMetaInterface.TYPE_DATE,
  ValueMetaInterface.TYPE_BOOLEAN, ValueMetaInterface.TYPE_BIGNUMBER, ValueMetaInterface.TYPE_STRING ) );
if ( !supported.contains( t ) ) throw new IllegalArgumentException( "No zero defined for type " + t );

Type guard

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

Try / catch

try {
  return ValueDataUtil.getZeroForValueMetaType( type );
} catch ( KettleValueException e ) {
  if ( e.getMessage() != null && e.getMessage().startsWith( "get zero function undefined" ) ) {
    return null; // binary/serializable/inet etc. have no natural zero
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling getZeroForValueMetaType with a ValueMetaInterface of a type the switch doesn't cover — e.g. TYPE_BINARY, TYPE_SERIALIZABLE, TYPE_INET, TYPE_TIMESTAMP on older Pentaho versions where the switch predates the type, or a custom value meta plugin.

Common situations: Row contains a Binary/Serializable/Internet-address column and the calling code assumed every column type has a zero; upgrading/downgrading Pentaho versions where the type set changed; custom ValueMeta plugins.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java:2276

    if ( type == null ) {
      throw new KettleValueException( "API error. ValueMetaInterface can't be null!" );
    }

    switch ( type.getType() ) {
      case ( ValueMetaInterface.TYPE_INTEGER ) : {
        return new Long( 0 );
      }
      case ( ValueMetaInterface.TYPE_NUMBER ) : {
        return new Double( 0 );
      }
      case ( ValueMetaInterface.TYPE_BIGNUMBER ) : {
        return new BigDecimal( 0 );
      }
      case ( ValueMetaInterface.TYPE_STRING ) : {
        return "";
      }
      default : {
        throw new KettleValueException( "get zero function undefined for data type: " + type.getType() );
      }
    }
  }
}

View on GitHub (pinned to f3058517a1)