pentaho/pentaho-kettle · error · KettleStepException
DimensionLookup.Exception.ErrorDetectedInGettingKey
Error message
DimensionLookup.Exception.ErrorDetectedInGettingKey
What it means
While constructing the lookup row, the step tries to copy each key value from the input row using precomputed keynrs indexes. If reading row[data.keynrs[i]] fails (index out of range or value conversion problem), it throws a KettleStepException reporting the key index i, the failing position keynrs[i]/row size, and the whole row as a string.
Solutions
- Re-save/re-run the transformation so the step re-initializes keynrs against the current row layout
- Ensure no upstream step changes the field count/order dynamically between init and execution
- Verify the key fields in the Dimension Lookup dialog match the actual incoming fields
- Log the incoming row before the step (e.g. with a 'Stream Lookup'/'Write to Log' step) to see the actual row shape
Example fix
// before: upstream Select Values removes a key field conditionally // row has 4 fields, keynrs[2]=5 -> index out of range // after: make field layout stable (always emit all fields, use null when absent), // or re-map keys in the dialog so indexes resolve within rowMeta.size()
Defensive patterns
Strategy: type-guard
Validate before calling
// confirm row layout hasn't changed since step init
if (rowMeta.size() < expectedMinFieldCount) {
throw new IllegalStateException("Input row narrower than expected; check upstream steps");
} Type guard
boolean keyIndexesInBounds(int[] keynrs, int rowSize) {
for (int k : keynrs) if (k < 0 || k >= rowSize) return false;
return true;
} Try / catch
try {
lookupValues(rowMeta, row);
} catch (KettleStepException e) {
if (e.getMessage().contains("ErrorDetectedInGettingKey")) {
logError("Row layout mismatch: " + e.getMessage());
} else { throw e; }
} Prevention
- Keep the upstream field layout stable; avoid conditionally removing fields
- Re-run/save the transformation after any upstream field change so indexes are recomputed
- Use Write-to-Log before the step to inspect actual row structure during development
When it happens
Trigger: lookupValues builds lookupRow for every incoming row; a mismatch between the row metadata captured at init and the actual row length (e.g. keynrs points past rowMeta.size()) causes the exception.
Common situations: Upstream step changed the number/order of fields after step initialization (dynamic schemas); two hops or modified rows injected mid-transformation; hand-edited transformation XML leaving stale keynrs indexes.
Related errors
- KettleStepException(cause) wrapping field conversion error…
- AnalyticQueryMeta.Exception.SubjectFieldNotFound
- BaseStep.Exception.MetadataDoesntMatchDataRowSize
- BaseStep.SafeMode.Exception.DoubleFieldnames
- BaseStep.SafeMode.Exception.MixingLayout
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/21717785d83e2d70.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/dimensionlookup/DimensionLookup.java:408
//
int index = data.preloadCache.lookupRow( lookupRow );
if ( index >= 0 ) {
returnRow = data.preloadCache.getRow( index );
} else {
returnRow = null; // Nothing found!
}
} else {
lookupRow = new Object[ data.lookupRowMeta.size() ];
lookupRowMeta = data.lookupRowMeta;
// Construct the lookup row...
//
for ( int i = 0; i < meta.getKeyStream().length; i++ ) {
try {
lookupRow[ i ] = row[ data.keynrs[ i ] ];
} catch ( Exception e ) { // TODO : remove exception??
throw new KettleStepException(
BaseMessages
.getString(
PKG,
"DimensionLookup.Exception.ErrorDetectedInGettingKey", i + "", data.keynrs[ i ] + "/" + rowMeta.size(),
rowMeta.getString( row ) ) );
}
}
lookupRow[ meta.getKeyStream().length ] = valueDate; // ? >= date_from
lookupRow[ meta.getKeyStream().length + 1 ] = valueDate; // ? < date_to
if ( isDebug() ) {
logDebug( BaseMessages.getString( PKG, "DimensionLookup.Log.LookupRow" )
+ data.lookupRowMeta.getString( lookupRow ) );
}
// Do the lookup and see if we can find anything in the database.
// But before that, let's see if we can find anything in the cacheView on GitHub (pinned to f3058517a1)