pentaho/pentaho-kettle · error · KettleValueException
API error. ValueMetaInterface can't be null!
Error message
API error. ValueMetaInterface can't be null!
What it means
ValueDataUtil.getZeroForValueMetaType returns the zero value (0, 0.0, BigDecimal.ZERO, "", etc.) for a given ValueMetaInterface type, and explicitly rejects a null argument with this KettleValueException as an API contract check.
Solutions
- Pass a non-null ValueMetaInterface — resolve the field from RowMetaInterface first and fail early if it is missing
- Guard the call: if ( type != null ) before invoking getZeroForValueMetaType
- Fix the lookup that produced null (check field names/case and step connectivity)
- If you only need a zero for a known type constant, construct it directly instead of via ValueMeta
Example fix
// before Object zero = ValueDataUtil.getZeroForValueMetaType( rowMeta.getValueMeta( idx ) ); // idx out of range => null // after ValueMetaInterface type = idx >= 0 && idx < rowMeta.size() ? rowMeta.getValueMeta( idx ) : null; Object zero = ( type != null ) ? ValueDataUtil.getZeroForValueMetaType( type ) : null;
Defensive patterns
Strategy: type-guard
Validate before calling
if ( type == null ) { throw new IllegalArgumentException( "ValueMetaInterface must not be null" ); } Type guard
ValueMetaInterface requireValueMeta( ValueMetaInterface m ) { if ( m == null ) throw new IllegalArgumentException( "null ValueMeta" ); return m; } Try / catch
try {
return ValueDataUtil.getZeroForValueMetaType( type );
} catch ( KettleValueException e ) {
if ( e.getMessage() != null && e.getMessage().contains( "can't be null" ) ) {
log.error( "ValueMeta lookup produced null — check field name/step mapping" );
return null;
}
throw e;
} Prevention
- Never pass through the result of rowMeta.getValueMeta(idx) without an index bounds check
- Fail fast on missing fields during transformation initialization
- Verify field names and case when resolving metadata lookups
When it happens
Trigger: Calling ValueDataUtil.getZeroForValueMetaType(null) — typically when a ValueMeta lookup returned null, e.g. a field was absent from the row meta or a metadata lookup failed and the null was passed straight through.
Common situations: Field removed/renamed upstream so getFieldFromRow/getValueMeta returns null; programmatically built ValueMeta objects where type resolution was skipped; plugin code assuming a field always exists in the row.
Related errors
- AddSequence.Exception.CouldNotFindNextValueForSequence
- ChangeFileEncoding.Error.SourceFileIsEmpty
- CloneRow.Log.NrClonesIsNull
- Output filename not set!
- Reference key ' ': value is not null while the compare…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/0b6f8b67bcbddde5.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java:2259
} catch ( Exception e ) {
throw new KettleValueException( e );
} finally {
IOUtils.closeQuietly( file );
}
return encoding;
}
/**
* Default utility method to get exact zero value according to ValueMetaInterface. Using
* this utility method saves from ClassCastExceptions later.
*
* @param type
* @return
* @throws KettleValueException
*/
public static Object getZeroForValueMetaType( ValueMetaInterface type ) throws KettleValueException {
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)