pentaho/pentaho-kettle · error · KettleStepException
StreamLookup.Log.GotRowWithoutKeys
Error message
StreamLookup.Log.GotRowWithoutKeys
What it means
If the lookup stream contained rows but the step was configured with zero key stream fields, there is no key to look up; when cache rows exist the step cannot pick a match and throws the GotRowWithoutKeys message. This indicates a misconfigured step (no keys defined) at runtime.
Solutions
- Open the StreamLookup step and define at least one key field pair (stream field -> lookup field)
- If an unconditional 'first row' lookup is truly intended, restructure using 'Get rows from result' or a different join strategy instead
- If building metadata programmatically, call allocateStreams()/setKeystream() and setKeylookup() before running
- Re-export/re-save the transformation to regenerate the step metadata if fields were lost
Example fix
// before (meta XML, no keys) <keystream></keystream> // after <keystream>customer_id</keystream> <keylookup>customer_id</keylookup>
Defensive patterns
Strategy: validation
Validate before calling
if (meta.getKeystream() == null || meta.getKeystream().length == 0) {
throw new IllegalStateException("StreamLookup requires at least one key field pair");
} Type guard
boolean hasKeys(StreamLookupMeta meta) {
return meta.getKeystream() != null && meta.getKeystream().length > 0;
} Try / catch
try { processRow(); } catch (KettleStepException e) {
if (e.getMessage().contains("GotRowWithoutKeys")) { /* configure key fields */ }
throw e;
} Prevention
- Never leave the key mapping table empty in the step dialog
- When generating metadata programmatically, always set keystream/keylookup arrays
- Validate step configuration before running headless (Kitchen) executions
When it happens
Trigger: lookupValues: data.hasLookupRows is true, meta.getKeystream().length == 0, so getFromCache cannot be called and the exception is thrown unconditionally.
Common situations: Transformation saved with the key mapping table empty; a programmatic caller built StreamLookupMeta without setting keystream/keylookup pairs; metadata lost during transformation migration between PDI versions.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Error converting data while looking up value
- StreamLookup.Exception.CanNotUseIntegerPairAlgorithm
- StreamLookup.Exception.UnableToFindField
- StreamLookup.Log.FieldNotFound
- StreamLookupMeta.Exception.ReturnValueCanNotBeFound
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/ccdabcb7c2a116ee.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/streamlookup/StreamLookup.java:273
// Change the input value to match the lookup value
//
lu[i] = lookupValue.convertDataCompatible( inputValue, lu[i] );
} catch ( KettleValueException e ) {
throw new KettleStepException( "Error converting data while looking up value", e );
}
}
}
}
Object[] add = null;
if ( data.hasLookupRows ) {
try {
if ( meta.getKeystream().length > 0 ) {
add = getFromCache( data.cacheKeyMeta, lu );
} else {
// Just take the first element in the hashtable...
throw new KettleStepException( BaseMessages.getString( PKG, "StreamLookup.Log.GotRowWithoutKeys" ) );
}
} catch ( Exception e ) {
throw new KettleStepException( e );
}
}
if ( add == null ) { // nothing was found, unknown code: add the specified default value...
add = data.nullIf;
}
return RowDataUtil.addRowData( row, rowMeta.size(), add );
}
private void addToCache( RowMetaInterface keyMeta, Object[] keyData, RowMetaInterface valueMeta,
Object[] valueData ) throws KettleValueException {
if ( meta.isMemoryPreservationActive() ) {
if ( meta.isUsingSortedList() ) {
KeyValue keyValue = new KeyValue( keyData, valueData );View on GitHub (pinned to f3058517a1)