pentaho/pentaho-kettle · error · RuntimeException
Unable to verify if [] is null or not because of an error:
Error message
Unable to verify if [] is null or not because of an error:
What it means
ValueMetaBase.isNull(Object) wraps its null-detection logic in a try/catch for ClassCastException and rethrows it as a RuntimeException. The null check casts data (e.g. byte[] for binary-string storage via convertBinaryStringToNativeType), so if the runtime data object does not match the declared value metadata type, the cast fails. This is a data/metadata mismatch, not a null-value question.
Solutions
- Align the data with the metadata: ensure the object passed to isNull matches the declared type/storage type (byte[] for binary-string storage, Long for integer, etc.).
- Verify the row metadata used for the row actually describes the row (RowMetaInterfacegetRowMeta().searchValueMeta) — fix the upstream step producing mismatched rows.
- Before calling isNull, convert data explicitly: e.g. meta.convertData(sourceMeta, data) so the runtime type fits.
- Catch RuntimeException around isNull if third-party rows may be malformed, and log the value metadata (toString()) to diagnose.
Example fix
// before
if (valueMeta.isNull(rowData[i])) { ... } // may throw if type mismatched
// after
if (rowData[i] == null) { ... }
else if (valueMeta.getStorageType() == ValueMetaInterface.STORAGE_TYPE_BINARY_STRING
&& !(rowData[i] instanceof byte[])) {
// treat as data/metadata mismatch; handle explicitly
} else {
if (valueMeta.isNull(rowData[i])) { ... }
} Defensive patterns
Strategy: type-guard
Validate before calling
if (meta.isStorageBinaryString() && !(data instanceof byte[])) {
throw new IllegalArgumentException("Expected byte[] for binary-string storage on " + meta.toStringMeta());
} Type guard
boolean dataMatchesMeta(ValueMetaInterface m, Object data) {
if (data == null) return true;
if (m.isStorageBinaryString()) return data instanceof byte[];
switch (m.getType()) {
case ValueMetaInterface.TYPE_STRING: return data instanceof String;
case ValueMetaInterface.TYPE_INTEGER: return data instanceof Long;
case ValueMetaInterface.TYPE_NUMBER: return data instanceof Double;
case ValueMetaInterface.TYPE_BOOLEAN: return data instanceof Boolean;
case ValueMetaInterface.TYPE_DATE: return data instanceof java.util.Date;
case ValueMetaInterface.TYPE_BIGNUMBER: return data instanceof java.math.BigDecimal;
case ValueMetaInterface.TYPE_BINARY: return data instanceof byte[];
default: return false;
}
} Try / catch
try { boolean isNull = meta.isNull(data); } catch (RuntimeException e) {
logger.logError("isNull failed, data/metadata mismatch on " + meta.toStringMeta() + ": " + e.getMessage());
} Prevention
- Verify row metadata matches actual row objects at step boundaries (RowMetaUtil / trans.getTransMeta().checkRowReferences).
- Never reuse one field's ValueMeta to inspect another field's data.
- Convert data with meta.convertData(sourceMeta, data) before null/compare operations.
- Enable transformation debug row-listener checks during development.
When it happens
Trigger: Calling isNull(Object) (directly or via compare/sort) where the data object's runtime class does not fit the metadata: e.g. metadata says STORAGE_TYPE_BINARY_STRING but data is not byte[], or metadata type is Integer/Date while data is a String/other object passed through convertBinaryStringToNativeType.
Common situations: Rows read from mixed sources where step metadata and actual row layout disagree; reusing a ValueMeta from one field to inspect another field's data; plugin steps that populate rows without honoring the declared row meta; unit tests feeding raw Strings into typed ValueMeta.
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
- GPLoadDataOutput.Exception.TypeNotSupported
- MappingInput.Exception.IllegalArgumentSourceStep
- MappingInput.Exception.IllegalArgumentStepName
- MappingInput.Exception.IllegalArgumentValueRename
- Stream Lookup comparator error
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/7404356bae16716b.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:3625
}
if ( emptyStringDiffersFromNull ) {
return false;
}
// If it's a string and the string is empty, it's a null value as well
//
if ( isString() ) {
if ( value.toString().length() == 0 ) {
return true;
}
}
// We tried everything else so we assume this value is not null.
//
return false;
} catch ( ClassCastException e ) {
throw new RuntimeException( "Unable to verify if [" + toString() + "] is null or not because of an error:"
+ e.toString(), e );
}
}
/*
* Compare 2 binary strings, one byte at a time.<br> This algorithm is very fast but most likely wrong as well.<br>
*
* @param one The first binary string to compare with
*
* @param two the second binary string to compare to
*
* @return -1 if <i>one</i> is smaller than <i>two</i>, 0 is both byte arrays are identical and 1 if <i>one</i> is
* larger than <i>two</i> protected int compareBinaryStrings(byte[] one, byte[] two) {
*
* for (int i=0;i<one.length;i++) { if (i>=two.length) return 1; // larger if (one[i]>two[i]) return 1; // larger if
* (one[i]<two[i]) return -1; // smaller } if (one.length>two.length) return 1; // larger if (one.length>two.length)
* return -11; // smaller return 0; }
*/View on GitHub (pinned to f3058517a1)